OVERALL YEARLY ANALYSES
Plot of 100% MCP HRs against number of relocations
year <- read_csv("GM_Consolidated_ByYear.csv")
Missing column names filled in: 'X13' [13]Parsed with column specification:
cols(
Year = [32mcol_double()[39m,
Gila = [31mcol_character()[39m,
Sex = [31mcol_character()[39m,
Environment = [31mcol_character()[39m,
Home_Range_100mcp = [32mcol_double()[39m,
N100 = [32mcol_double()[39m,
Home_Range_95mcp = [32mcol_double()[39m,
N95 = [32mcol_double()[39m,
Home_Range_95kde = [32mcol_double()[39m,
N = [32mcol_double()[39m,
Home_Range_50kde = [32mcol_double()[39m,
N50 = [32mcol_double()[39m,
X13 = [33mcol_logical()[39m
)
# quick plot
# Graph1<-ggplot(year,aes(x=N100,y=Home_Range_100mcp,group=Environment))+
Graph1<-ggplot(year,aes(x=N100,y=Home_Range_100mcp))+
geom_point(aes(shape = factor(Environment)), size = 2)+
geom_smooth(aes(linetype=Environment),colour="black", method="lm") +
# scale_colour_manual(values=c(subsidized="cyan3",nonsubsidized="indian red1"))+
# labs(title = "100% MCP Home Ranges")+
xlab("Number of Relocations")+
ylab("100% MCP Area (ha)")+
# labs(caption = "Figure 3 | Non-Subsidized (Owl Head Buttes) vs. Subsidized (Stone Canyon) population 100% MCPs against number \n of fixes of the complete data set.")+
theme(plot.caption = element_text(hjust = 0,lineheight = 0.9))
# theme_bw()
Graph1<-Graph1+theme(axis.title=element_text(size = 14))
# legend at top-left, inside the plot
SCOH.hr.fig<-Graph1 + theme(legend.title = element_blank(),
legend.text = element_text(size = 12),
legend.justification=c(0,1),
legend.position=c(0.05, 0.95),
legend.background = element_blank(),
legend.key = element_blank(),
legend.box.background = element_rect(colour = "black")) +
scale_shape_discrete(name ="",
breaks=c("nonsubsidized", "subsidized"),
labels=c("Nonsubsidized", "Subsidized")) +
scale_linetype_discrete(name ="",
breaks=c("nonsubsidized", "subsidized"),
labels=c("Nonsubsidized", "Subsidized"))
SCOH.hr.fig

# dir.create("outputs") # create a new folder to hold the output files
# ggsave("outputs/SC_OHB_plot.pdf")
Overall combined 100% MCP means averaged across sex
library(Rmisc)
Means <- summarySE(year, measurevar="Home_Range_100mcp",
groupvars=c("Environment"),na.rm = TRUE)
kable(Means, format = "pandoc", caption = 'Overall combined 100% MCP means averaged across sex')
Overall combined 100% MCP means averaged across sex
| nonsubsidized |
26 |
33.44231 |
20.518658 |
4.0240400 |
8.287665 |
| subsidized |
53 |
10.40151 |
6.948743 |
0.9544832 |
1.915311 |
Overall combined 95% MCP means averaged across sex
Means.95mcp <- summarySE(year, measurevar="Home_Range_95mcp",
groupvars=c("Environment"),na.rm = TRUE)
Means.95mcp
Set projection for mapping
CRS.SC<-CRS("+proj=utm +zone=12 +ellps=WGS84 +units=m +no_defs")
Function for MCP analysis
Function of MCP polygons used for mapping
Function of KDE analysis
kde_analysis.href.plot <- function(filename, percentage){
data <- read.csv(file = filename)
x <- as.data.frame(data$EASTING)
y <- as.data.frame(data$NORTHING)
xy <- c(x,y)
data.proj <- SpatialPointsDataFrame(xy,data, proj4string = CRS.SC)
xy <- SpatialPoints(data.proj@coords)
kde<-kernelUD(xy, h="href", kern="bivnorm", grid=1000)
ver <- getverticeshr(kde, percentage)
area <- as.data.frame(round(ver$area,4))
.rowNamesDF(area, make.names=TRUE) <- data$LIZARDNUMBER
write.table(area,file="KDE_Hectares.csv",
append=TRUE,sep=",", col.names=FALSE, row.names=TRUE)
kde.points <- cbind((data.frame(data.proj@coords)),data$LIZARDNUMBER)
colnames(kde.points) <- c("x","y","lizardnumber")
kde.poly <- fortify(ver, region = "id")
units <- grid.text(paste(round(ver$area,2)," ha"), x=0.9, y=0.95,
gp=gpar(fontface=4, cex=0.9), draw = FALSE)
kde.plot <- ggplot() +
geom_polygon(data=kde.poly, aes(x=kde.poly$long, y=kde.poly$lat), alpha = 0.5) +
geom_point(data=kde.points, aes(x=x, y=y)) + theme_bw() +
labs(x="Easting (m)", y="Northing (m)", title=kde.points$lizardnumber) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5)) +
annotation_custom(units)
kde.plot
}
Function of KDE polygons for mapping
kde_analysis.href.polygon <- function(filename, percentage){
data <- read.csv(file = filename)
x <- as.data.frame(data$EASTING)
y <- as.data.frame(data$NORTHING)
xy <- c(x,y)
data.proj <- SpatialPointsDataFrame(xy,data, proj4string = CRS.SC)
xy <- SpatialPoints(data.proj@coords)
kde<-kernelUD(xy, h="href", kern="bivnorm", grid=1000)
ver <- getverticeshr(kde, percentage)
ver@proj4string<-CRS.SC
area <- as.data.frame(round(ver$area,4))
.rowNamesDF(area, make.names=TRUE) <- data$YEAR
write.table(area,file="KDE_Hectares.csv",
append=TRUE,sep=",", col.names=FALSE, row.names=TRUE)
kde.points <- cbind((data.frame(data.proj@coords)),data$YEAR)
colnames(kde.points) <- c("x","y","year")
kde.poly <- fortify(ver, region = "id")
units <- grid.text(paste(round(ver$area,2)," ha"), x=0.9, y=0.95,
gp=gpar(fontface=4, cex=0.9), draw = FALSE)
ver
}
Function of raster of UD
# kde_analysis.href.raster <- function(filename){
# data <- read.csv(file = filename)
# x <- as.data.frame(data$EASTING)
# y <- as.data.frame(data$NORTHING)
# xy <- c(x,y)
# data.proj <- SpatialPointsDataFrame(xy,data, proj4string = CRS.SC)
# xy <- SpatialPoints(data.proj@coords)
# kde<-kernelUD(xy, h="href", kern="bivnorm", grid=1000)
# kde<-as(kde, "SpatialGridDataFrame")
# kde@proj4string<- CRS.SC
# kde
# }
Function of trajectory analysis and distance over time
traj_analysis <- function(filename){
relocs_data <- read.csv(file = filename)
relocs <- as.ltraj(cbind(relocs_data$EASTING, relocs_data$NORTHING),id=relocs_data$LIZARDNUMBER, typeII = FALSE, date=NULL)
relocs.df <- ld(relocs)
relocs_dist <- as.data.frame(sum(sapply(relocs.df$dist, sum, na.rm=TRUE)))
colnames(relocs_dist) <- "Total Distance"
name <- relocs.df$id[1]
row.names(relocs_dist) <- name
relocs_units <- grid.text(paste(round(relocs_dist,2),"m"), x=0.9, y=0.9,
gp=gpar(fontface=3, col="black", cex=0.9), draw = FALSE)
reloc.plot <- ggplot() + theme_classic() + geom_path(data=relocs.df, aes(x=x,y=y), linetype = "dashed", colour = "red",
arrow = arrow(length=unit(.5,"cm"), angle = 20, ends="last", type = "closed")) +
geom_point(data=relocs.df, aes(x=x, y=y)) + geom_point(data=relocs.df, aes(x=x[1],
y=y[1]), size = 3, color = "darkgreen", pch=0) +
labs(x="Easting (m)", y="Northing (m)", title=relocs.df$id[1]) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5)) +
annotation_custom(relocs_units)
reloc.plot
}
Function of distance of time
dist_analysis <- function(filename){
relocs_data <- read.csv(file = filename)
relocs <- as.ltraj(cbind(relocs_data$EASTING, relocs_data$NORTHING),id=relocs_data$LIZARDNUMBER, typeII = FALSE, date=NULL)
relocs.df <- ld(relocs)
relocs_dist <- as.data.frame(sum(sapply(relocs.df$dist, sum, na.rm=TRUE)))
colnames(relocs_dist) <- "Total Distance"
name <- relocs.df$id[1]
row.names(relocs_dist) <- name
write.table(relocs_dist,file="reloc_dist.csv",
append=TRUE,sep=",", col.names=FALSE, row.names=TRUE)
dist.plot
}
Map of yearly HR shifts of a subset of Gila Monsters. Includes running MCP polygons, Fortify mcp polygons for ggplot2 by YEAR
M215_mcp.11<-mcp_analysis.POLY("./M215/2011 .csv", percentage= 100)
M215_mcp.12<-mcp_analysis.POLY("./M215/2012 .csv", percentage= 100)
F104_mcp.08<-mcp_analysis.POLY("./F104/2008 .csv", percentage= 100)
F104_mcp.09<-mcp_analysis.POLY("./F104/2009 .csv", percentage= 100)
F114_mcp.08<-mcp_analysis.POLY("./F114/2008 .csv", percentage= 100)
F114_mcp.09<-mcp_analysis.POLY("./F114/2009 .csv", percentage= 100)
F114_mcp.10<-mcp_analysis.POLY("./F114/2010 .csv", percentage= 100)
F114_mcp.11<-mcp_analysis.POLY("./F114/2011 .csv", percentage= 100)
F114_mcp.12<-mcp_analysis.POLY("./F114/2012 .csv", percentage= 100)
F137_mcp.09<-mcp_analysis.POLY("./F137/2009 .csv", percentage= 100)
F137_mcp.10<-mcp_analysis.POLY("./F137/2010 .csv", percentage= 100)
F137_mcp.11<-mcp_analysis.POLY("./F137/2011 .csv", percentage= 100)
F147_mcp.09<-mcp_analysis.POLY("./F147/2009 .csv", percentage= 100)
F147_mcp.10<-mcp_analysis.POLY("./F147/2010 .csv", percentage= 100)
F147_mcp.11<-mcp_analysis.POLY("./F147/2011 .csv", percentage= 100)
F147_mcp.12<-mcp_analysis.POLY("./F147/2012 .csv", percentage= 100)
F36_mcp.08<-mcp_analysis.POLY("./F36/2008 .csv", percentage= 100)
F36_mcp.09<-mcp_analysis.POLY("./F36/2009 .csv", percentage= 100)
F36_mcp.10<-mcp_analysis.POLY("./F36/2010 .csv", percentage= 100)
F36_mcp.11<-mcp_analysis.POLY("./F36/2011 .csv", percentage= 100)
F36_mcp.12<-mcp_analysis.POLY("./F36/2012 .csv", percentage= 100)
F66_mcp.08<-mcp_analysis.POLY("./F66/2008 .csv", percentage= 100)
F66_mcp.09<-mcp_analysis.POLY("./F66/2009 .csv", percentage= 100)
F66_mcp.10<-mcp_analysis.POLY("./F66/2010 .csv", percentage= 100)
M119_mcp.08<-mcp_analysis.POLY("./M119/2008 .csv", percentage= 100)
M119_mcp.09<-mcp_analysis.POLY("./M119/2009 .csv", percentage= 100)
M119_mcp.10<-mcp_analysis.POLY("./M119/2010 .csv", percentage= 100)
M112_mcp.07<-mcp_analysis.POLY("./M112/2007 .csv", percentage= 100)
M112_mcp.09<-mcp_analysis.POLY("./M112/2009 .csv", percentage= 100)
M112_mcp.10<-mcp_analysis.POLY("./M112/2010 .csv", percentage= 100)
M69_mcp.09<-mcp_analysis.POLY("./M69/2009 .csv", percentage= 100)
M69_mcp.10<-mcp_analysis.POLY("./M69/2010 .csv", percentage= 100)
## Fortify mcp polygons for ggplot2 *YEAR*:
F104_mcp.08T <- fortify(F104_mcp.08, region = "id")
F104_mcp.09T <- fortify(F104_mcp.09, region = "id")
F114_mcp.08T <- fortify(F114_mcp.08, region = "id")
F114_mcp.09T <- fortify(F114_mcp.09, region = "id")
F114_mcp.10T <- fortify(F114_mcp.10, region = "id")
F114_mcp.11T <- fortify(F114_mcp.11, region = "id")
F114_mcp.12T <- fortify(F114_mcp.12, region = "id")
F137_mcp.09T <- fortify(F137_mcp.09, region = "id")
F137_mcp.10T <- fortify(F137_mcp.10, region = "id")
F137_mcp.11T <- fortify(F137_mcp.11, region = "id")
F147_mcp.09T <- fortify(F147_mcp.09, region = "id")
F147_mcp.10T <- fortify(F147_mcp.10, region = "id")
F147_mcp.11T <- fortify(F147_mcp.11, region = "id")
F147_mcp.12T <- fortify(F147_mcp.12, region = "id")
F36_mcp.08T <- fortify(F36_mcp.08, region = "id")
F36_mcp.09T <- fortify(F36_mcp.09, region = "id")
F36_mcp.10T <- fortify(F36_mcp.10, region = "id")
F36_mcp.11T <- fortify(F36_mcp.11, region = "id")
F36_mcp.12T <- fortify(F36_mcp.12, region = "id")
F66_mcp.08T <- fortify(F66_mcp.08, region = "id")
F66_mcp.09T <- fortify(F66_mcp.09, region = "id")
F66_mcp.10T <- fortify(F66_mcp.10, region = "id")
M119_mcp.08T <- fortify(M119_mcp.08, region = "id")
M119_mcp.09T <- fortify(M119_mcp.09, region = "id")
M119_mcp.10T <- fortify(M119_mcp.10, region = "id")
M112_mcp.07T <- fortify(M112_mcp.07, region = "id")
M112_mcp.09T <- fortify(M112_mcp.09, region = "id")
M112_mcp.10T <- fortify(M112_mcp.10, region = "id")
M69_mcp.09T <- fortify(M69_mcp.09, region = "id")
M69_mcp.10T <- fortify(M69_mcp.10, region = "id")
M215_mcp.11T <- fortify(M215_mcp.11, region = "id")
M215_mcp.12T <- fortify(M215_mcp.12, region = "id")
mcp.shift.TEST4 <- ggplot() +
# geom_polygon(data=F104_mcp.08T, aes(x=F104_mcp.08T$long, y=F104_mcp.08T$lat),
# alpha=0.1,colour="black",linetype=2) +
# geom_polygon(data=F104_mcp.09T, aes(x=F104_mcp.09T$long, y=F104_mcp.09T$lat),
# alpha=0.1,colour="black",linetype=2) +
geom_polygon(data=F114_mcp.08T, aes(x=F114_mcp.08T$long, y=F114_mcp.08T$lat),
alpha=0.1,colour="black",linetype=3) +
geom_polygon(data=F114_mcp.09T, aes(x=F114_mcp.09T$long, y=F114_mcp.09T$lat),
alpha=0.1,colour="black",linetype=3) +
geom_polygon(data=F114_mcp.10T, aes(x=F114_mcp.10T$long, y=F114_mcp.10T$lat),
alpha=0.1,colour="black",linetype=3) +
geom_polygon(data=F114_mcp.11T, aes(x=F114_mcp.11T$long, y=F114_mcp.11T$lat),
alpha=0.1,colour="black",linetype=3) +
geom_polygon(data=F114_mcp.12T, aes(x=F114_mcp.12T$long, y=F114_mcp.12T$lat),
alpha=0.1,colour="black",linetype=3) +
geom_polygon(data=F137_mcp.09T, aes(x=F137_mcp.09T$long, y=F137_mcp.09T$lat),
alpha=0.1,colour="brown",linetype=4) +
geom_polygon(data=F137_mcp.10T, aes(x=F137_mcp.10T$long, y=F137_mcp.10T$lat),
alpha=0.1,colour="brown",linetype=4) +
geom_polygon(data=F137_mcp.11T, aes(x=F137_mcp.11T$long, y=F137_mcp.11T$lat),
alpha=0.1,colour="brown",linetype=4) +
geom_polygon(data=F147_mcp.09T, aes(x=F147_mcp.09T$long, y=F147_mcp.09T$lat),
alpha=0.1,colour="red",linetype=1) +
geom_polygon(data=F147_mcp.10T, aes(x=F147_mcp.10T$long, y=F147_mcp.10T$lat),
alpha=0.1,colour="red",linetype=1) +
geom_polygon(data=F147_mcp.11T, aes(x=F147_mcp.11T$long, y=F147_mcp.11T$lat),
alpha=0.1,colour="red",linetype=1) +
geom_polygon(data=F147_mcp.12T, aes(x=F147_mcp.12T$long, y=F147_mcp.12T$lat),
alpha=0.1,colour="red",linetype=1) +
# geom_polygon(data=F36_mcp.08T, aes(x=F36_mcp.08T$long, y=F36_mcp.08T$lat),
# alpha=0.1,colour="black",linetype=6) +
# geom_polygon(data=F36_mcp.09T, aes(x=F36_mcp.09T$long, y=F36_mcp.09T$lat),
# alpha=0.1,colour="black",linetype=6) +
# geom_polygon(data=F36_mcp.10T, aes(x=F36_mcp.10T$long, y=F36_mcp.10T$lat),
# alpha=0.1,colour="black",linetype=6) +
# geom_polygon(data=F36_mcp.11T, aes(x=F36_mcp.11T$long, y=F36_mcp.11T$lat),
# alpha=0.1,colour="black",linetype=6) +
# geom_polygon(data=F36_mcp.12T, aes(x=F36_mcp.12T$long, y=F36_mcp.12T$lat),
# alpha=0.1,colour="black",linetype=6) +
geom_polygon(data=F66_mcp.08T, aes(x=F66_mcp.08T$long, y=F66_mcp.08T$lat),
alpha=0.1,colour="green",linetype=5) +
geom_polygon(data=F66_mcp.09T, aes(x=F66_mcp.09T$long, y=F66_mcp.09T$lat),
alpha=0.1,colour="green",linetype=5) +
geom_polygon(data=F66_mcp.10T, aes(x=F66_mcp.10T$long, y=F66_mcp.10T$lat),
alpha=0.1,colour="green",linetype=5) +
geom_polygon(data=M119_mcp.08T, aes(x=M119_mcp.08T$long, y=M119_mcp.08T$lat),
alpha=0.1,colour="blue",linetype=6) +
geom_polygon(data=M119_mcp.09T, aes(x=M119_mcp.09T$long, y=M119_mcp.09T$lat),
alpha=0.1,colour="blue",linetype=6) +
geom_polygon(data=M119_mcp.10T, aes(x=M119_mcp.10T$long, y=M119_mcp.10T$lat),
alpha=0.1,colour="blue",linetype=6) +
geom_polygon(data=M112_mcp.07T, aes(x=M112_mcp.07T$long, y=M112_mcp.07T$lat),
alpha=0.1,colour="purple",linetype=2) +
geom_polygon(data=M112_mcp.09T, aes(x=M112_mcp.09T$long, y=M112_mcp.09T$lat),
alpha=0.1,colour="purple",linetype=2) +
geom_polygon(data=M112_mcp.10T, aes(x=M112_mcp.10T$long, y=M112_mcp.10T$lat),
alpha=0.1,colour="purple",linetype=2) +
# geom_polygon(data=M69_mcp.09T, aes(x=M69_mcp.09T$long, y=M69_mcp.09T$lat),
# alpha=0.1,colour="black") +
# geom_polygon(data=M69_mcp.10T, aes(x=M69_mcp.10T$long, y=M69_mcp.10T$lat),
# alpha=0.1,colour="black") +
# geom_polygon(data=M215_mcp.11T, aes(x=M215_mcp.11T$long, y=M215_mcp.11T$lat),
# alpha=0.1,colour="black") +
# geom_polygon(data=M215_mcp.12T, aes(x=M215_mcp.12T$long, y=M215_mcp.12T$lat),
# alpha=0.1,colour="black") +
theme_bw() +labs(x="Easting (m)", y="Northing (m)") +
labs(caption = "Figure 5 | SC Yearly home range shifts of 8 lizards, both males and females. Home range shifts appear to be \n relativley stable over study years.")+
theme(plot.caption = element_text(hjust = 0,lineheight = 0.9))
# theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5))
## within each geom_polygon line?:
## aes(colour="red"or"M112_mcp.09T")...+scale_color_manual(name="",breaks=c("","",...""))+
## values=c(""="",...)
mcp.shift.TEST4
Raw group 100% MCP home range means of Stone Canyon and Owl Head Buttes. Grouped by environment and sex
library(Rmisc)
YR_GRP_Means <- summarySE(year, measurevar="Home_Range_100mcp",
groupvars=c("Environment","Sex"),na.rm = TRUE)
kable(YR_GRP_Means, format = "pandoc",
caption = 'Table 1 | Raw group 100% MCP home range means of Stone Canyon and Owl Head Buttes. Grouped by environment and sex.')
Raw group 95% MCP home range means of Stone Canyon and Owl Head Buttes. Grouped by environment and sex
YR_GRP_Means95 <- summarySE(year, measurevar="Home_Range_95mcp",
groupvars=c("Environment","Sex"),na.rm = TRUE)
kable(YR_GRP_Means95, format = "pandoc", caption = 'Table 2 | Raw group 95% MCP home range means of raw data of Stone Canyon and Owl Head Buttes. Grouped by environment and sex.')
RM-ANOVA for 100% MCP analyses between the subsidized and non-subsidized
# Get p-values from mixed model F values:
library(lme4)
library(readr)
year <- read_csv("GM_Consolidated_ByYear.csv")
RMmod.year<-lmer(Home_Range_100mcp~Environment+Year+Sex+N100+Environment*Sex+
(1|Gila),data = year)
summary(RMmod.year)
ANOVA table for 100% MCPs between the two populations
anova(RMmod.year)
RM-ANOVA for 95% MCP analyses between the subsidized and non-subsidized
RMmod.year95<-lmer(Home_Range_95mcp~Environment+Year+Sex+N100+Environment*Sex+
(1|Gila),data = year)
summary(RMmod.year95)
ANOVA table for 95% MCPs between the two populations
anova(RMmod.year95)
Raw group means AND adjusted EMMs of Yearly Overall 100%MCP

Directional means of home range (100% MCP) after being adjusted for year, sex and sample size
kable(ref_dfRM_sex, format = "pandoc", caption = 'Table | Directional means of home range (100% MCP) after being adjusted for year, sex and sample size.')
RM-ANOVA of 95% KDEs for the subsidized population
RM.KDEmod.year<-lmer(Home_Range_95kde~Year+Sex+N+(1|Gila),data = sub)
summary(RM.KDEmod.year)
ANOVA Table for 95%KDE
anova(RM.KDEmod.year)
RM-ANOVA of 50% KDEs for the subsidized
RM.KDE.50.mod.year<-lmer(Home_Range_50kde~Year+Sex+N+(1|Gila),data = sub)
summary(RM.KDE.50.mod.year)
ANOVA Talbe of 50% KDE for the subsidized
anova(RM.KDE.50.mod.year)
TABLE. Raw Group 50% KDE home range means male and female home ranges at Stone Canyon
YR_GRP_Means.50KDE <- summarySE(sub, measurevar="Home_Range_50kde",
groupvars=c("Sex"),na.rm = TRUE)
kable(YR_GRP_Means.50KDE, format = "pandoc", caption = 'Table 5 | Raw Group 50% KDE home range means male and female home ranges at Stone Canyon.')
Raw group means AND adjusted EMMs of Yearly Overall 95% KDEs between non/subsidized populations

Collective grid of 100% MCP and 95% KDE of both sites from above
ggarrange(Raw.YearHR, yr.mean.adj, Raw.kde, kde.mean.adj, labels = c("A", "B", "C","D"),
ncol = 2, nrow = 2)

43.4 male 42.9 female Yearly overall means of 95% KDEs grouped by site and sex
YR_Means.95KDEall <- summarySE(year, measurevar="Home_Range_95kde",
groupvars=c("Environment","Sex"),na.rm = TRUE)
kable(YR_Means.95KDEall, format = "pandoc", caption = 'Table | Raw Group 95% KDE home range means male and female home ranges at non/subsidized.')
Table | Raw Group 95% KDE home range means male and female home ranges at non/subsidized.
| nonsubsidized |
female |
5 |
36.80000 |
9.603905 |
4.294997 |
11.924824 |
| nonsubsidized |
male |
6 |
69.40000 |
27.763789 |
11.334520 |
29.136310 |
| subsidized |
female |
37 |
22.98892 |
11.046272 |
1.815996 |
3.683010 |
| subsidized |
male |
13 |
35.00308 |
12.057546 |
3.344161 |
7.286302 |
Pairwise Comparisons, between sexes by environment, and between environments averaged across sex
RMmod.year.Em<-lmer(Home_Range_100mcp~Environment+Year+Sex+N100+Environment*Sex+
(1|Gila),data = year)
# RMmod.year.Em95<-lmer(Home_Range_95mcp~Environment+Year+Sex+N95+Environment*Sex+
# (1|Gila),data = year)
# Sex.emm.oa <- emmeans(RMmod.year.Em, c("Environment","Sex"))
# pairs(Sex.emm.oa)
emm_s.t2 <- emmeans(RMmod.year.Em, pairwise ~ Sex | Environment)
emm_s.t2
# emm_s.e1 <- emmeans(RMmod.year.Em, pairwise ~ Environment)
# emm_s.e1
Graphical Comparisons of Sex Within Each Environment:
plot(emm_s.t2, comparisons = TRUE, xlab = "Least Square Mean (ha)", ylab = "Environment")
Pairwise by sex between enviornements 100% MCP, and 95% KDEs
emm_s.t3 <- emmeans(RMmod.year.Em, pairwise ~ Environment | Sex)
emm_s.t3
# emm_s.t95 <- emmeans(RMmod.year.Em95, pairwise ~ Environment | Sex)
# emm_s.t95
Graphical Comparisons of Sex between the two populations:
plot(emm_s.t3, comparisons = TRUE, xlab = "Least Square Mean (ha)", ylab = "Environment")
Ineractive map of MCPs at Stone Canyon
M67_MCP<-mcp_analysis.POLY('./M67/M67 .csv', percentage= 100)
M69_MCP<-mcp_analysis.POLY('./M69/M69 .csv', percentage= 100)
M255_MCP<-mcp_analysis.POLY('./M255/M255 .csv', percentage= 100)
M215_MCP<-mcp_analysis.POLY('./M215/M215 .csv', percentage= 100)
M14_MCP<-mcp_analysis.POLY('./M14/M14 .csv', percentage= 100)
M119_MCP<-mcp_analysis.POLY('./M119/M119 .csv', percentage= 100)
M112_MCP<-mcp_analysis.POLY('./M112/M112 .csv', percentage= 100)
F66_MCP<-mcp_analysis.POLY('./F66/F66 .csv', percentage= 100)
F36_MCP<-mcp_analysis.POLY('./F36/F36 .csv', percentage= 100)
F252_MCP<-mcp_analysis.POLY('./F252/F252 .csv', percentage= 100)
F214_MCP<-mcp_analysis.POLY('./F214/F214 .csv', percentage= 100)
F200_MCP<-mcp_analysis.POLY('./F200/F200 .csv', percentage= 100)
F147_MCP<-mcp_analysis.POLY('./F147/F147 .csv', percentage= 100)
F146_MCP<-mcp_analysis.POLY('./F146/F146 .csv', percentage= 100)
F137_MCP<-mcp_analysis.POLY('./F137/F137 .csv', percentage= 100)
F135_MCP<-mcp_analysis.POLY('./F135/F135 .csv', percentage= 100)
F114_MCP<-mcp_analysis.POLY('./F114/F114 .csv', percentage= 100)
F104_MCP<-mcp_analysis.POLY('./F104/F104 .csv', percentage= 100)
Male.MCP <- rbind(M67_MCP,M69_MCP,M255_MCP,M215_MCP,M14_MCP,M119_MCP,M112_MCP)
Female.MCP <- rbind(F66_MCP,F36_MCP,F252_MCP,F214_MCP,F200_MCP,F147_MCP,F146_MCP,F137_MCP,
F135_MCP,F114_MCP,F104_MCP)
mapviewOptions(basemaps = c("OpenStreetMap","Esri.WorldImagery","OpenTopoMap"),
na.color = "magenta",
layers.control.pos = "topleft")
mapview(Male.MCP, legend=F, zcol="id", col.regions = c("blue"), alpha.regions=0.3) +
mapview(Female.MCP, legend=F, zcol = "id", col.regions = c("red"), alpha.regions=0.3)
Create stagnant stamen map of MCPs at Stone Canyon
Error: Don't know how to add north2(SC_stamen_map, x = 0.89, y = 0.85, scale = 0.1, symbol = 16) to a plot

Interactive map of KDEs at Stone Canyon
M67_KDE<-kde_analysis.href.polygon('./M67/M67 .csv', percentage= 95)
M69_KDE<-kde_analysis.href.polygon('./M69/M69 .csv', percentage= 95)
M255_KDE<-kde_analysis.href.polygon('./M255/M255 .csv', percentage= 95)
M215_KDE<-kde_analysis.href.polygon('./M215/M215 .csv', percentage= 95)
M14_KDE<-kde_analysis.href.polygon('./M14/M14 .csv', percentage= 95)
M119_KDE<-kde_analysis.href.polygon('./M119/M119 .csv', percentage= 95)
M112_KDE<-kde_analysis.href.polygon('./M112/M112 .csv', percentage= 95)
F66_KDE<-kde_analysis.href.polygon('./F66/F66 .csv', percentage= 95)
F36_KDE<-kde_analysis.href.polygon('./F36/F36 .csv', percentage= 95)
F252_KDE<-kde_analysis.href.polygon('./F252/F252 .csv', percentage= 95)
F214_KDE<-kde_analysis.href.polygon('./F214/F214 .csv', percentage= 95)
F200_KDE<-kde_analysis.href.polygon('./F200/F200 .csv', percentage= 95)
F147_KDE<-kde_analysis.href.polygon('./F147/F147 .csv', percentage= 95)
F146_KDE<-kde_analysis.href.polygon('./F146/F146 .csv', percentage= 95)
F137_KDE<-kde_analysis.href.polygon('./F137/F137 .csv', percentage= 95)
F135_KDE<-kde_analysis.href.polygon('./F135/F135 .csv', percentage= 95)
F114_KDE<-kde_analysis.href.polygon('./F114/F114 .csv', percentage= 95)
F104_KDE<-kde_analysis.href.polygon('./F104/F104 .csv', percentage= 95)
Male.KDE <- rbind(M67_KDE,M69_KDE,M255_KDE,M215_KDE,M14_KDE,M119_KDE,M112_KDE)
Female.KDE <- rbind(F66_KDE,F36_KDE,F252_KDE,F214_KDE,F200_KDE,F147_KDE,F146_KDE,F137_KDE,
F135_KDE,F114_KDE,F104_KDE)
mapviewOptions(basemaps = c("OpenStreetMap","Esri.WorldImagery","OpenTopoMap"),
na.color = "magenta",
layers.control.pos = "topleft")
mapview(Male.KDE, legend=F, zcol="id", col.regions = c("blue"), alpha.regions=0.3) +
mapview(Female.KDE, legend=F, zcol = "id", col.regions = c("red"), alpha.regions=0.3)
TABLE
Table | Subsidized and non-subsidized directional means of KDE home ranges after being adjusted for year, sex and sample size.
| nonsubsidized |
female |
42.44837 |
9.346459 |
53.01148 |
23.70185 |
61.19490 |
| subsidized |
female |
20.93992 |
4.083131 |
22.92042 |
12.49169 |
29.38814 |
| nonsubsidized |
male |
80.81873 |
9.084540 |
52.50968 |
62.59348 |
99.04398 |
| subsidized |
male |
35.27439 |
5.501543 |
29.24014 |
24.02648 |
46.52229 |
SEASONAL ANALYSES
Map of seasonal fluctions of home ranges
## Create MCP polygons by SEASON:
M215_mcp.EM<-mcp_analysis.POLY("./M215/Emergence .csv", percentage= 100)
M215_mcp.DRY<-mcp_analysis.POLY("./M215/Dry .csv", percentage= 100)
M215_mcp.MON<-mcp_analysis.POLY("./M215/Monsoon .csv", percentage= 100)
M112_mcp.DRY<-mcp_analysis.POLY("./M112/Dry .csv", percentage= 100)
M112_mcp.MON<-mcp_analysis.POLY("./M112/Monsoon .csv", percentage= 100)
M112_mcp.PM<-mcp_analysis.POLY("./M112/Post_Monsoon .csv", percentage= 100)
M119_mcp.DRY<-mcp_analysis.POLY("./M119/Dry .csv", percentage= 100)
M119_mcp.MON<-mcp_analysis.POLY("./M119/Monsoon .csv", percentage= 100)
M119_mcp.PM<-mcp_analysis.POLY("./M119/Post_Monsoon .csv", percentage= 100)
F114_mcp.EM<-mcp_analysis.POLY("./F114/Emergence .csv", percentage= 100)
F114_mcp.DRY<-mcp_analysis.POLY("./F114/Dry .csv", percentage= 100)
F114_mcp.MON<-mcp_analysis.POLY("./F114/Monsoon .csv", percentage= 100)
F114_mcp.PM<-mcp_analysis.POLY("./F114/Post_Monsoon .csv", percentage= 100)
F137_mcp.EM<-mcp_analysis.POLY("./F137/Emergence .csv", percentage= 100)
F137_mcp.DRY<-mcp_analysis.POLY("./F137/Dry .csv", percentage= 100)
F137_mcp.MON<-mcp_analysis.POLY("./F137/Monsoon .csv", percentage= 100)
F137_mcp.PM<-mcp_analysis.POLY("./F137/Post_Monsoon .csv", percentage= 100)
F147_mcp.EM<-mcp_analysis.POLY("./F147/Emergence .csv", percentage= 100)
F147_mcp.DRY<-mcp_analysis.POLY("./F147/Dry .csv", percentage= 100)
F147_mcp.MON<-mcp_analysis.POLY("./F147/Monsoon .csv", percentage= 100)
F147_mcp.PM<-mcp_analysis.POLY("./F147/Post_Monsoon .csv", percentage= 100)
F252_mcp.EM<-mcp_analysis.POLY("./F252/Emergence .csv", percentage= 100)
F252_mcp.DRY<-mcp_analysis.POLY("./F252/Dry .csv", percentage= 100)
F252_mcp.MON<-mcp_analysis.POLY("./F252/Monsoon .csv", percentage= 100)
F252_mcp.PM<-mcp_analysis.POLY("./F252/Post_Monsoon .csv", percentage= 100)
F36_mcp.EM<-mcp_analysis.POLY("./F36/Emergence .csv", percentage= 100)
F36_mcp.DRY<-mcp_analysis.POLY("./F36/Dry .csv", percentage= 100)
F36_mcp.MON<-mcp_analysis.POLY("./F36/Monsoon .csv", percentage= 100)
F36_mcp.PM<-mcp_analysis.POLY("./F36/Post_Monsoon .csv", percentage= 100)
F66_mcp.EM<-mcp_analysis.POLY("./F66/Emergence .csv", percentage= 100)
F66_mcp.DRY<-mcp_analysis.POLY("./F66/Dry .csv", percentage= 100)
F66_mcp.MON<-mcp_analysis.POLY("./F66/Monsoon .csv", percentage= 100)
F66_mcp.PM<-mcp_analysis.POLY("./F66/Post_Monsoon .csv", percentage= 100)
## Fortify mcp polygons for ggplot2 *SEASON*:
M215_mcp.EMT <- fortify(M215_mcp.EM, region = "id")
M215_mcp.DRYT <- fortify(M215_mcp.DRY, region = "id")
M215_mcp.MONT <- fortify(M215_mcp.MON, region = "id")
M112_mcp.DRYT <- fortify(M112_mcp.DRY, region = "id")
M112_mcp.MONT <- fortify(M112_mcp.MON, region = "id")
M112_mcp.PMT <- fortify(M112_mcp.PM, region = "id")
M119_mcp.DRYT <- fortify(M119_mcp.DRY, region = "id")
M119_mcp.MONT <- fortify(M119_mcp.MON, region = "id")
M119_mcp.PMT <- fortify(M119_mcp.PM, region = "id")
F114_mcp.EMT <- fortify(F114_mcp.EM, region = "id")
F114_mcp.DRYT <- fortify(F114_mcp.DRY, region = "id")
F114_mcp.MONT <- fortify(F114_mcp.MON, region = "id")
F114_mcp.PMT <- fortify(F114_mcp.PM, region = "id")
F137_mcp.EMT <- fortify(F137_mcp.EM, region = "id")
F137_mcp.DRYT <- fortify(F137_mcp.DRY, region = "id")
F137_mcp.MONT <- fortify(F137_mcp.MON, region = "id")
F137_mcp.PMT <- fortify(F137_mcp.PM, region = "id")
F147_mcp.EMT <- fortify(F147_mcp.EM, region = "id")
F147_mcp.DRYT <- fortify(F147_mcp.DRY, region = "id")
F147_mcp.MONT <- fortify(F147_mcp.MON, region = "id")
F147_mcp.PMT <- fortify(F147_mcp.PM, region = "id")
F252_mcp.EMT <- fortify(F252_mcp.EM, region = "id")
F252_mcp.DRYT <- fortify(F252_mcp.DRY, region = "id")
F252_mcp.MONT <- fortify(F252_mcp.MON, region = "id")
F252_mcp.PMT <- fortify(F252_mcp.PM, region = "id")
F36_mcp.EMT <- fortify(F36_mcp.EM, region = "id")
F36_mcp.DRYT <- fortify(F36_mcp.DRY, region = "id")
F36_mcp.MONT <- fortify(F36_mcp.MON, region = "id")
F36_mcp.PMT <- fortify(F36_mcp.PM, region = "id")
F66_mcp.EMT <- fortify(F66_mcp.EM, region = "id")
F66_mcp.DRYT <- fortify(F66_mcp.DRY, region = "id")
F66_mcp.MONT <- fortify(F66_mcp.MON, region = "id")
F66_mcp.PMT <- fortify(F66_mcp.PM, region = "id")
mcp.shift.TEST5 <- ggplot() +
geom_polygon(data=F114_mcp.EMT, aes(x=F114_mcp.EMT$long, y=F114_mcp.EMT$lat),
alpha=0.1,colour="blue",linetype=2) +
geom_polygon(data=F114_mcp.DRYT, aes(x=F114_mcp.DRYT$long, y=F114_mcp.DRYT$lat),
alpha=0.1,colour="red",linetype=3) +
geom_polygon(data=F114_mcp.MONT, aes(x=F114_mcp.MONT$long, y=F114_mcp.MONT$lat),
alpha=0.1,colour="green",linetype=4) +
geom_polygon(data=F114_mcp.PMT, aes(x=F114_mcp.PMT$long, y=F114_mcp.PMT$lat),
alpha=0.1,colour="black",linetype=5) +
geom_polygon(data=F137_mcp.EMT, aes(x=F137_mcp.EMT$long, y=F137_mcp.EMT$lat),
alpha=0.1,colour="blue",linetype=2) +
geom_polygon(data=F137_mcp.DRYT, aes(x=F137_mcp.DRYT$long, y=F137_mcp.DRYT$lat),
alpha=0.1,colour="red",linetype=3) +
geom_polygon(data=F137_mcp.MONT, aes(x=F137_mcp.MONT$long, y=F137_mcp.MONT$lat),
alpha=0.1,colour="green",linetype=4) +
geom_polygon(data=F137_mcp.PMT, aes(x=F137_mcp.PMT$long, y=F137_mcp.PMT$lat),
alpha=0.1,colour="black",linetype=5) +
geom_polygon(data=F147_mcp.EMT, aes(x=F147_mcp.EMT$long, y=F147_mcp.EMT$lat),
alpha=0.1,colour="blue",linetype=2) +
geom_polygon(data=F147_mcp.DRYT, aes(x=F147_mcp.DRYT$long, y=F147_mcp.DRYT$lat),
alpha=0.1,colour="red",linetype=3) +
geom_polygon(data=F147_mcp.MONT, aes(x=F147_mcp.MONT$long, y=F147_mcp.MONT$lat),
alpha=0.1,colour="green",linetype=4) +
geom_polygon(data=F147_mcp.PMT, aes(x=F147_mcp.PMT$long, y=F147_mcp.PMT$lat),
alpha=0.1,colour="black",linetype=5) +
# geom_polygon(data=F252_mcp.EMT, aes(x=F252_mcp.EMT$long, y=F252_mcp.EMT$lat),
# alpha=0.1,colour="black",linetype=2) +
# geom_polygon(data=F252_mcp.DRYT, aes(x=F252_mcp.DRYT$long, y=F252_mcp.DRYT$lat),
# alpha=0.1,colour="black",linetype=3) +
# geom_polygon(data=F252_mcp.MONT, aes(x=F252_mcp.MONT$long, y=F252_mcp.MONT$lat),
# alpha=0.1,colour="black",linetype=4) +
# geom_polygon(data=F252_mcp.PMT, aes(x=F252_mcp.PMT$long, y=F252_mcp.PMT$lat),
# alpha=0.1,colour="black",linetype=5) +
geom_polygon(data=F36_mcp.EMT, aes(x=F36_mcp.EMT$long, y=F36_mcp.EMT$lat),
alpha=0.1,colour="blue",linetype=2) +
geom_polygon(data=F36_mcp.DRYT, aes(x=F36_mcp.DRYT$long, y=F36_mcp.DRYT$lat),
alpha=0.1,colour="red",linetype=3) +
geom_polygon(data=F36_mcp.MONT, aes(x=F36_mcp.MONT$long, y=F36_mcp.MONT$lat),
alpha=0.1,colour="green",linetype=4) +
geom_polygon(data=F36_mcp.PMT, aes(x=F36_mcp.PMT$long, y=F36_mcp.PMT$lat),
alpha=0.1,colour="black",linetype=5) +
geom_polygon(data=F66_mcp.EMT, aes(x=F66_mcp.EMT$long, y=F66_mcp.EMT$lat),
alpha=0.1,colour="blue",linetype=2) +
geom_polygon(data=F66_mcp.DRYT, aes(x=F66_mcp.DRYT$long, y=F66_mcp.DRYT$lat),
alpha=0.1,colour="red",linetype=3) +
geom_polygon(data=F66_mcp.MONT, aes(x=F66_mcp.MONT$long, y=F66_mcp.MONT$lat),
alpha=0.1,colour="green",linetype=4) +
geom_polygon(data=F66_mcp.PMT, aes(x=F66_mcp.PMT$long, y=F66_mcp.PMT$lat),
alpha=0.1,colour="black",linetype=5) +
theme_bw() +
labs(x="Easting (m)", y="Northing (m)") +
labs(caption = "Figure 6 | SC seasonal home range shifts of five lizards. All seasonal polygons stay relatively stable with \n considerable overlap and without any major shifts.")+
theme(plot.caption = element_text(hjust = 0,lineheight = 0.9))+
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5))
mcp.shift.TEST5
TABLE group means of seasonal home ranges between the two populations averaged across sex
seasonal<-read.csv("SC_Seasonal_Data.csv")
library(Rmisc)
SEAS_GRP_Means <- summarySE(seasonal, measurevar="Home_Range_100mcp",
groupvars=c("Environment","Season"), na.rm = TRUE)
# SEAS_GRP_Means
kable(SEAS_GRP_Means, format = "pandoc", caption = 'Table 6 | Group means of seasonal home ranges between Stone Canyon (subsidized) and Owl Head Buttes (non-subsidized). These means are averaged across sex.')
RM-ANOVA for seasonal home ranges between environments
library(lme4)
library(readr)
library(lmerTest)
# seasonal<-read.csv("SC_Seasonal_Data.csv")
RM.mod.Season <- lmer(Home_Range_100mcp~Environment+Season+Sex+N+Environment*Season+(1|Gila),
data=seasonal)
summary(RM.mod.Season)
ANOVA table of seasonal HRs between envs.
anova(RM.mod.Season)
TABLE of seasonal home ranges by sex between the two populations
SEAS_GRP_TEST <- summarySE(seasonal, measurevar="Home_Range_100mcp",
groupvars=c("Environment","Season","Sex"), na.rm = TRUE)
# SEAS_GRP_Means
kable(SEAS_GRP_TEST, format = "pandoc", caption = 'Table 7 | Seasonal home range means between Stone Canyon (subsidized) and Owl Head Buttes (non-subsidized) popuations for males and females. These are raw means before being adjusted for environment, season, sex, and sample size.')
figures for raw seasonal home ranges between the two populations

Figures Adjusted EMMs of seasonal home range between the two populations

Collective grid of raw and adjusted seasonal home ranges
ggarrange(raw.seasonal, adj.seasonal, labels = c("A", "B"),
nrow = 2)

Post hoc analyses of seasonal home ranges
Pairwise of each season between populations, overaged over levels of sex
emm_s.t <- emmeans(RM.mod.Season, pairwise ~ Environment | Season)
emm_s.t
Graphical comparisons
plot(emm_s.t, comparisons = TRUE)
Pairwise between seasons within each popultion
emm_s.t4 <- emmeans(RM.mod.Season, pairwise ~ Season | Environment)
emm_s.t4
Graphical Comps
plot(emm_s.t4, comparisons = TRUE)
Pairwise between sexes of each season of the subsidized population
sub <- subset(seasonal, Environment == "subsidized")
RM.mod.Sub <- lmer(Home_Range_100mcp~Season+Sex+N+Season*Sex+(1|Gila), data=sub)
emm_s.t5 <- emmeans(RM.mod.Sub, pairwise ~ Sex | Season)
emm_s.t5
Graphical Comps
plot(emm_s.t5, comparisons = TRUE)
Pairwise between sexes of each season of the non-subsidized population
nonsub <- subset(seasonal, Environment == "nonsubsidized")
View(nonsub)
RM.mod.NSub <- lmer(Home_Range_100mcp~Season+Sex+N+Season*Sex+(1|Gila), data=nonsub)
emm_s.t6 <- emmeans(RM.mod.NSub, pairwise ~ Sex | Season)
emm_s.t6
Graphical Comps
plot(emm_s.t6, comparisons = TRUE)
LS0tCnRpdGxlOiAiU3BhdGlhbCBTY3JpcHRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgoKCmBgYHtyfQpwYWNrcmF0Ojppbml0KCJ+L0Rlc2t0b3AvSGVsb2Rlcm1hIFNwYXRpYWwvSGVsb2Rlcm1hIFNwYXRpYWwiKQpgYGAKCgoKYGBge3J9CiMgcmVxdWlyZWQgcGFja2FnZXMKbGlicmFyeShhZGVoYWJpdGF0SFIpICNmb3IgaG9tZSByYW5nZSBjYWxjdWxhdGlvbnMKbGlicmFyeShkYXRhLnRhYmxlKSAjbWFuaXB1bGF0ZSBTMyBhbmQgUzQgZGF0YSB0YWJsZXMKbGlicmFyeShnZ3Bsb3QyKSAjZm9yIGdyYXBoaWMgb3V0cHV0CmxpYnJhcnkoZ2dmb3J0aWZ5KSAjdG8gYWxsb3cgZ2dwbG90MiB0byByZWFkIHNwYXRpYWwgZGF0YQpsaWJyYXJ5KGdyaWQpICN0byBhZGQgYW5ub3RhdGlvbnMgdG8gdGhlIG91dHB1dAojIGxpYnJhcnkoT3BlblN0cmVldE1hcCkgI2ZvciBvYnRhaW5pbmcgcmFzdGVyIGltYWdlcwpsaWJyYXJ5KHBiYXBwbHkpICNuZWVkZWQgZm9yIHByb2dyZXNzIGJhcgpsaWJyYXJ5KHBsb3RseSkgI2ZvciBpbnRlcmFjdGl2ZSB4eSBwbG90CmxpYnJhcnkocmdkYWwpICNmb3IgY29udmVydGluZyBzcGF0aWFsIGRhdGEKbGlicmFyeShzcCkgI2ZvciBjb252ZXJ0aW5nIHNwYXRpYWwgZGF0YQpsaWJyYXJ5KHJnZW9zKQojIGxpYnJhcnkocmFzdGVyKQpsaWJyYXJ5KG1hcHZpZXcpCgpgYGAKCgoKCgpPdmVyYWxsIGluZGl2aWR1YWwgeWVhcmx5IGhvbWUgcmFuZ2VzIGZvciBub24vc3Vic2lkaXplZCBwb3B1bGF0aW9ucwpgYGB7ciBlY2hvPUZBTFNFfQpHTV90YWJsZSA8LSByZWFkX2NzdigiR01fdGFibGUuY3N2IikKa2FibGUoR01fdGFibGUsZm9ybWF0PSJwYW5kb2MiLCBjYXB0aW9uPSdUYWJsZSAxIHwgUG9vbGVkIG92ZXJhbGwgaG9tZSByYW5nZXMgb2YgR2lsYSBNb25zdGVycyBhdCBPd2wgSGVhZCBCdXR0ZXMgYW5kIFN0b25lIENhbnlvbiBHb2xmIENsdWIuIEJvdGggMTAwJSBhbmQgOTUlIE1DUHMgd2VyZSBjYWxjdWxhdGVkIGJldHdlZW4gYm90aCBwb3B1bGF0aW9ucy4nKQpgYGAKCgoKCgpHaWxhIG1vbnN0ZXIgbG9jYXRpb25zIGZvciBhbGwgdHJhY2tlZCBsaXphcmRzIGFjcm9zcyBTdG9uZSBDYW55b24KYGBge3J9CkFsbC5HaWxhcyA8LSByZWFkX2NzdigiLi9HTV9GaW5hbF9EYXRhLmNzdiIpCgp1dG1fcG9pbnRzIDwtIGNiaW5kKEFsbC5HaWxhcyRFQVNUSU5HLCBBbGwuR2lsYXMkTk9SVEhJTkcpCgp1dG1fbG9jYXRpb25zIDwtIFNwYXRpYWxQb2ludHModXRtX3BvaW50cywgcHJvajRzdHJpbmc9Q1JTLlNDKQoKcHJval9sYXQubG9uIDwtIGFzLmRhdGEuZnJhbWUoc3BUcmFuc2Zvcm0odXRtX2xvY2F0aW9ucywgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKSkKY29sbmFtZXMocHJval9sYXQubG9uKSA8LSBjKCJ4IiwieSIpCgojIyBGT1JUSUdZIFNQQVRJQUwgU1BBVElBTCBQT0lOVFMgRk9SIFBMT1RUSU5HOgpwcm9qX2xhdC5sb24gPC0gZm9ydGlmeShwcm9qX2xhdC5sb24sIHJlZ2lvbiA9ICJUeXBlIikKCm15TWFwIDwtIGdldF9zdGFtZW5tYXAoYmJveCA9IGMobGVmdCA9IC0xMTEuMDA5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IDMyLjQ1OSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWdodCA9IC0xMTAuOTY5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcCA9IDMyLjQ3NCksCiAgICAgICAgICAgICAgICAgICAgICAgbWFwdHlwZSA9ICJ0ZXJyYWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgY3JvcCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgIHpvb20gPSAxNSkKCmdnbWFwKG15TWFwKStnZW9tX3BvaW50KGRhdGE9cHJval9sYXQubG9uLCBhZXMoeD14LCB5PXkpLCBzaXplPTAuMykKYGBgCgoKCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBPVkVSQUxMIFlFQVJMWSBBTkFMWVNFUyAjIyMjIyMjIyMjIyMjIyMjIyMjIwoKClBsb3Qgb2YgMTAwJSAgTUNQIEhScyBhZ2FpbnN0IG51bWJlciBvZiByZWxvY2F0aW9ucwpgYGB7cn0KeWVhciA8LSByZWFkX2NzdigiR01fQ29uc29saWRhdGVkX0J5WWVhci5jc3YiKQoKIyBxdWljayBwbG90CiMgR3JhcGgxPC1nZ3Bsb3QoeWVhcixhZXMoeD1OMTAwLHk9SG9tZV9SYW5nZV8xMDBtY3AsZ3JvdXA9RW52aXJvbm1lbnQpKSsKR3JhcGgxPC1nZ3Bsb3QoeWVhcixhZXMoeD1OMTAwLHk9SG9tZV9SYW5nZV8xMDBtY3ApKSsKICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IGZhY3RvcihFbnZpcm9ubWVudCkpLCBzaXplID0gMikrCiAgZ2VvbV9zbW9vdGgoYWVzKGxpbmV0eXBlPUVudmlyb25tZW50KSxjb2xvdXI9ImJsYWNrIiwgbWV0aG9kPSJsbSIpICsKICAjIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoc3Vic2lkaXplZD0iY3lhbjMiLG5vbnN1YnNpZGl6ZWQ9ImluZGlhbiByZWQxIikpKwogICMgbGFicyh0aXRsZSA9ICIxMDAlIE1DUCBIb21lIFJhbmdlcyIpKwogIHhsYWIoIk51bWJlciBvZiBSZWxvY2F0aW9ucyIpKwogIHlsYWIoIjEwMCUgTUNQIEFyZWEgKGhhKSIpKwogICMgbGFicyhjYXB0aW9uID0gIkZpZ3VyZSAzIHwgTm9uLVN1YnNpZGl6ZWQgKE93bCBIZWFkIEJ1dHRlcykgdnMuIFN1YnNpZGl6ZWQgKFN0b25lIENhbnlvbikgcG9wdWxhdGlvbiAxMDAlIE1DUHMgYWdhaW5zdCBudW1iZXIgXG4gb2YgZml4ZXMgb2YgdGhlIGNvbXBsZXRlIGRhdGEgc2V0LiIpKwogIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsbGluZWhlaWdodCA9IDAuOSkpCiAgIyB0aGVtZV9idygpCgpHcmFwaDE8LUdyYXBoMSt0aGVtZShheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplID0gMTQpKQoKIyBsZWdlbmQgYXQgdG9wLWxlZnQsIGluc2lkZSB0aGUgcGxvdApTQ09ILmhyLmZpZzwtR3JhcGgxICsgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLAogICAgICAgICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbj1jKDAsMSksCiAgICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj1jKDAuMDUsIDAuOTUpLAogICAgICAgICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIpKSArCiAgICAgICAgICAgICAgIHNjYWxlX3NoYXBlX2Rpc2NyZXRlKG5hbWUgID0iIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9Yygibm9uc3Vic2lkaXplZCIsICJzdWJzaWRpemVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIk5vbnN1YnNpZGl6ZWQiLCAiU3Vic2lkaXplZCIpKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV9saW5ldHlwZV9kaXNjcmV0ZShuYW1lICA9IiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoIm5vbnN1YnNpZGl6ZWQiLCAic3Vic2lkaXplZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJOb25zdWJzaWRpemVkIiwgIlN1YnNpZGl6ZWQiKSkKClNDT0guaHIuZmlnCiMgZGlyLmNyZWF0ZSgib3V0cHV0cyIpICMgY3JlYXRlIGEgbmV3IGZvbGRlciB0byBob2xkIHRoZSBvdXRwdXQgZmlsZXMKIyBnZ3NhdmUoIm91dHB1dHMvU0NfT0hCX3Bsb3QucGRmIikKYGBgCgoKCgoKT3ZlcmFsbCBjb21iaW5lZCAxMDAlIE1DUCBtZWFucyBhdmVyYWdlZCBhY3Jvc3Mgc2V4CmBgYHtyfQpsaWJyYXJ5KFJtaXNjKQpNZWFucyA8LSBzdW1tYXJ5U0UoeWVhciwgbWVhc3VyZXZhcj0iSG9tZV9SYW5nZV8xMDBtY3AiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwdmFycz1jKCJFbnZpcm9ubWVudCIpLG5hLnJtID0gVFJVRSkKCmthYmxlKE1lYW5zLCBmb3JtYXQgPSAicGFuZG9jIiwgY2FwdGlvbiA9ICdPdmVyYWxsIGNvbWJpbmVkIDEwMCUgTUNQIG1lYW5zIGF2ZXJhZ2VkIGFjcm9zcyBzZXgnKQpgYGAKCgoKCgpPdmVyYWxsIGNvbWJpbmVkIDk1JSBNQ1AgbWVhbnMgYXZlcmFnZWQgYWNyb3NzIHNleApgYGB7cn0KTWVhbnMuOTVtY3AgPC0gc3VtbWFyeVNFKHllYXIsIG1lYXN1cmV2YXI9IkhvbWVfUmFuZ2VfOTVtY3AiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwdmFycz1jKCJFbnZpcm9ubWVudCIpLG5hLnJtID0gVFJVRSkKTWVhbnMuOTVtY3AKYGBgCgoKCgoKU2V0IHByb2plY3Rpb24gZm9yIG1hcHBpbmcKYGBge3J9CkNSUy5TQzwtQ1JTKCIrcHJvaj11dG0gK3pvbmU9MTIgK2VsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikKYGBgCgoKCgoKRnVuY3Rpb24gZm9yIE1DUCBhbmFseXNpcwpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQptY3BfYW5hbHlzaXMgPC0gZnVuY3Rpb24oZmlsZW5hbWUsIHBlcmNlbnRhZ2UpewogIGRhdGEgPC0gcmVhZC5jc3YoZmlsZSA9IGZpbGVuYW1lKQogIHggPC0gYXMuZGF0YS5mcmFtZShkYXRhJEVBU1RJTkcpCiAgeSA8LSBhcy5kYXRhLmZyYW1lKGRhdGEkTk9SVEhJTkcpCiAgeHkgPC0gYyh4LHkpCiAgZGF0YS5wcm9qIDwtIFNwYXRpYWxQb2ludHNEYXRhRnJhbWUoeHksZGF0YSwgcHJvajRzdHJpbmcgPSBDUlMuU0MpCiAgeHkgPC0gU3BhdGlhbFBvaW50cyhkYXRhLnByb2pAY29vcmRzKQogIG1jcC5vdXQgPC0gbWNwKHh5LCBwZXJjZW50YWdlLCB1bm91dD0iaGEiKQogIGFyZWEgPC0gYXMuZGF0YS5mcmFtZShyb3VuZChtY3Aub3V0QGRhdGEkYXJlYSw0KSkKICAucm93TmFtZXNERihhcmVhLCBtYWtlLm5hbWVzPVRSVUUpIDwtIGRhdGEkWUVBUgogIHdyaXRlLnRhYmxlKGFyZWEsZmlsZT0iTUNQX0hlY3RhcmVzLmNzdiIsCiAgICAgICAgICAgICAgYXBwZW5kPVRSVUUsc2VwPSIsIiwgY29sLm5hbWVzPUZBTFNFLCByb3cubmFtZXM9VFJVRSkKICBtY3AucG9pbnRzIDwtIGNiaW5kKChkYXRhLmZyYW1lKHh5KSksZGF0YSRZRUFSKQogIGNvbG5hbWVzKG1jcC5wb2ludHMpIDwtIGMoIngiLCJ5IiwgInllYXIiKQogIG1jcC5wb2x5IDwtIGZvcnRpZnkobWNwLm91dCwgcmVnaW9uID0gImlkIikKICB1bml0cyA8LSBncmlkLnRleHQocGFzdGUocm91bmQobWNwLm91dEBkYXRhJGFyZWEsMiksIiBoYSIpLCB4PTAuOSwgIHk9MC45NSwKICAgICAgICAgICAgICAgICAgICAgZ3A9Z3Bhcihmb250ZmFjZT00LCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQogIG1jcC5wbG90IDwtIGdncGxvdCgpICsKICAgIGdlb21fcG9seWdvbihkYXRhPW1jcC5wb2x5LCBhZXMoeD1tY3AucG9seSRsb25nLCB5PW1jcC5wb2x5JGxhdCksIGFscGhhPTAuNSkgKwogICAgZ2VvbV9wb2ludChkYXRhPW1jcC5wb2ludHMsIGFlcyh4PXgsIHk9eSkpICsgdGhlbWVfYncoKSArCiAgICBsYWJzKHg9IkVhc3RpbmcgKG0pIiwgeT0iTm9ydGhpbmcgKG0pIiwgdGl0bGU9bWNwLnBvaW50cyR5ZWFyKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSkgKwogICAgYW5ub3RhdGlvbl9jdXN0b20odW5pdHMpCiAgbWNwLnBsb3QKfQpgYGAKCgpGdW5jdGlvbiBvZiBNQ1AgcG9seWdvbnMgdXNlZCBmb3IgbWFwcGluZwpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIENSUy5TQzwtQ1JTKCIrcHJvaj11dG0gK3pvbmU9MTIgK2VsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikKCm1jcF9hbmFseXNpcy5QT0xZIDwtIGZ1bmN0aW9uKGZpbGVuYW1lLCBwZXJjZW50YWdlKXsKICBkYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSBmaWxlbmFtZSxzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCiAgZGF0YS5zcCA8LSBkYXRhWywgYygiTElaQVJETlVNQkVSIiwgIkVBU1RJTkciLCAiTk9SVEhJTkciKV0KICBjb29yZGluYXRlcyhkYXRhLnNwKSA8LSBjKCJFQVNUSU5HIiwgIk5PUlRISU5HIikKICBwcm9qNHN0cmluZyhkYXRhLnNwKSA8LSBDUlMuU0MKICBtY3Bfb3V0IDwtIG1jcChkYXRhLnNwLCBwZXJjZW50YWdlLCB1bm91dD0iaGEiKQp9CmBgYAoKCkZ1bmN0aW9uIG9mIEtERSBhbmFseXNpcwpgYGB7cn0Ka2RlX2FuYWx5c2lzLmhyZWYucGxvdCA8LSBmdW5jdGlvbihmaWxlbmFtZSwgcGVyY2VudGFnZSl7CiAgZGF0YSA8LSByZWFkLmNzdihmaWxlID0gZmlsZW5hbWUpCiAgeCA8LSBhcy5kYXRhLmZyYW1lKGRhdGEkRUFTVElORykKICB5IDwtIGFzLmRhdGEuZnJhbWUoZGF0YSROT1JUSElORykKICB4eSA8LSBjKHgseSkKICBkYXRhLnByb2ogPC0gU3BhdGlhbFBvaW50c0RhdGFGcmFtZSh4eSxkYXRhLCBwcm9qNHN0cmluZyA9IENSUy5TQykKICB4eSA8LSBTcGF0aWFsUG9pbnRzKGRhdGEucHJvakBjb29yZHMpCiAga2RlPC1rZXJuZWxVRCh4eSwgaD0iaHJlZiIsIGtlcm49ImJpdm5vcm0iLCBncmlkPTEwMDApCiAgdmVyIDwtIGdldHZlcnRpY2VzaHIoa2RlLCBwZXJjZW50YWdlKQogIGFyZWEgPC0gYXMuZGF0YS5mcmFtZShyb3VuZCh2ZXIkYXJlYSw0KSkKICAucm93TmFtZXNERihhcmVhLCBtYWtlLm5hbWVzPVRSVUUpIDwtIGRhdGEkTElaQVJETlVNQkVSCiAgd3JpdGUudGFibGUoYXJlYSxmaWxlPSJLREVfSGVjdGFyZXMuY3N2IiwKICAgICAgICAgICAgICBhcHBlbmQ9VFJVRSxzZXA9IiwiLCBjb2wubmFtZXM9RkFMU0UsIHJvdy5uYW1lcz1UUlVFKQogIGtkZS5wb2ludHMgPC0gY2JpbmQoKGRhdGEuZnJhbWUoZGF0YS5wcm9qQGNvb3JkcykpLGRhdGEkTElaQVJETlVNQkVSKQogIGNvbG5hbWVzKGtkZS5wb2ludHMpIDwtIGMoIngiLCJ5IiwibGl6YXJkbnVtYmVyIikKICBrZGUucG9seSA8LSBmb3J0aWZ5KHZlciwgcmVnaW9uID0gImlkIikKICB1bml0cyA8LSBncmlkLnRleHQocGFzdGUocm91bmQodmVyJGFyZWEsMiksIiBoYSIpLCB4PTAuOSwgIHk9MC45NSwKICAgICAgICAgICAgICAgICAgICAgZ3A9Z3Bhcihmb250ZmFjZT00LCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQogIGtkZS5wbG90IDwtIGdncGxvdCgpICsKICAgIGdlb21fcG9seWdvbihkYXRhPWtkZS5wb2x5LCBhZXMoeD1rZGUucG9seSRsb25nLCB5PWtkZS5wb2x5JGxhdCksIGFscGhhID0gMC41KSArCiAgICBnZW9tX3BvaW50KGRhdGE9a2RlLnBvaW50cywgYWVzKHg9eCwgeT15KSkgKyB0aGVtZV9idygpICsKICAgIGxhYnMoeD0iRWFzdGluZyAobSkiLCB5PSJOb3J0aGluZyAobSkiLCB0aXRsZT1rZGUucG9pbnRzJGxpemFyZG51bWJlcikgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSkpICsKICAgIGFubm90YXRpb25fY3VzdG9tKHVuaXRzKQogIGtkZS5wbG90Cn0KYGBgCgoKRnVuY3Rpb24gb2YgS0RFIHBvbHlnb25zIGZvciBtYXBwaW5nCmBgYHtyfQprZGVfYW5hbHlzaXMuaHJlZi5wb2x5Z29uIDwtIGZ1bmN0aW9uKGZpbGVuYW1lLCBwZXJjZW50YWdlKXsKICBkYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSBmaWxlbmFtZSkKICB4IDwtIGFzLmRhdGEuZnJhbWUoZGF0YSRFQVNUSU5HKQogIHkgPC0gYXMuZGF0YS5mcmFtZShkYXRhJE5PUlRISU5HKQogIHh5IDwtIGMoeCx5KQogIGRhdGEucHJvaiA8LSBTcGF0aWFsUG9pbnRzRGF0YUZyYW1lKHh5LGRhdGEsIHByb2o0c3RyaW5nID0gQ1JTLlNDKQogIHh5IDwtIFNwYXRpYWxQb2ludHMoZGF0YS5wcm9qQGNvb3JkcykKICBrZGU8LWtlcm5lbFVEKHh5LCBoPSJocmVmIiwga2Vybj0iYml2bm9ybSIsIGdyaWQ9MTAwMCkKICB2ZXIgPC0gZ2V0dmVydGljZXNocihrZGUsIHBlcmNlbnRhZ2UpCiAgdmVyQHByb2o0c3RyaW5nPC1DUlMuU0MKICBhcmVhIDwtIGFzLmRhdGEuZnJhbWUocm91bmQodmVyJGFyZWEsNCkpCiAgLnJvd05hbWVzREYoYXJlYSwgbWFrZS5uYW1lcz1UUlVFKSA8LSBkYXRhJFlFQVIKICB3cml0ZS50YWJsZShhcmVhLGZpbGU9IktERV9IZWN0YXJlcy5jc3YiLAogICAgICAgICAgICAgIGFwcGVuZD1UUlVFLHNlcD0iLCIsIGNvbC5uYW1lcz1GQUxTRSwgcm93Lm5hbWVzPVRSVUUpCiAga2RlLnBvaW50cyA8LSBjYmluZCgoZGF0YS5mcmFtZShkYXRhLnByb2pAY29vcmRzKSksZGF0YSRZRUFSKQogIGNvbG5hbWVzKGtkZS5wb2ludHMpIDwtIGMoIngiLCJ5IiwieWVhciIpCiAga2RlLnBvbHkgPC0gZm9ydGlmeSh2ZXIsIHJlZ2lvbiA9ICJpZCIpCiAgdW5pdHMgPC0gZ3JpZC50ZXh0KHBhc3RlKHJvdW5kKHZlciRhcmVhLDIpLCIgaGEiKSwgeD0wLjksICB5PTAuOTUsCiAgICAgICAgICAgICAgICAgICAgIGdwPWdwYXIoZm9udGZhY2U9NCwgY2V4PTAuOSksIGRyYXcgPSBGQUxTRSkKICB2ZXIKfQpgYGAKCgpGdW5jdGlvbiBvZiByYXN0ZXIgb2YgVUQgCmBgYHtyfQojIGtkZV9hbmFseXNpcy5ocmVmLnJhc3RlciA8LSBmdW5jdGlvbihmaWxlbmFtZSl7CiMgICBkYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSBmaWxlbmFtZSkKIyAgIHggPC0gYXMuZGF0YS5mcmFtZShkYXRhJEVBU1RJTkcpCiMgICB5IDwtIGFzLmRhdGEuZnJhbWUoZGF0YSROT1JUSElORykKIyAgIHh5IDwtIGMoeCx5KQojICAgZGF0YS5wcm9qIDwtIFNwYXRpYWxQb2ludHNEYXRhRnJhbWUoeHksZGF0YSwgcHJvajRzdHJpbmcgPSBDUlMuU0MpCiMgICB4eSA8LSBTcGF0aWFsUG9pbnRzKGRhdGEucHJvakBjb29yZHMpCiMgICBrZGU8LWtlcm5lbFVEKHh5LCBoPSJocmVmIiwga2Vybj0iYml2bm9ybSIsIGdyaWQ9MTAwMCkKIyAgIGtkZTwtYXMoa2RlLCAiU3BhdGlhbEdyaWREYXRhRnJhbWUiKQojICAga2RlQHByb2o0c3RyaW5nPC0gQ1JTLlNDCiMgICBrZGUKIyB9CmBgYAoKCkZ1bmN0aW9uIG9mIHRyYWplY3RvcnkgYW5hbHlzaXMgYW5kIGRpc3RhbmNlIG92ZXIgdGltZQpgYGB7cn0KdHJhal9hbmFseXNpcyA8LSBmdW5jdGlvbihmaWxlbmFtZSl7CiAgcmVsb2NzX2RhdGEgPC0gcmVhZC5jc3YoZmlsZSA9IGZpbGVuYW1lKQogIHJlbG9jcyA8LSBhcy5sdHJhaihjYmluZChyZWxvY3NfZGF0YSRFQVNUSU5HLCByZWxvY3NfZGF0YSROT1JUSElORyksaWQ9cmVsb2NzX2RhdGEkTElaQVJETlVNQkVSLCB0eXBlSUkgPSBGQUxTRSwgZGF0ZT1OVUxMKQogIHJlbG9jcy5kZiA8LSBsZChyZWxvY3MpCiAgcmVsb2NzX2Rpc3QgPC0gYXMuZGF0YS5mcmFtZShzdW0oc2FwcGx5KHJlbG9jcy5kZiRkaXN0LCBzdW0sIG5hLnJtPVRSVUUpKSkKICBjb2xuYW1lcyhyZWxvY3NfZGlzdCkgPC0gIlRvdGFsIERpc3RhbmNlIgogIG5hbWUgPC0gcmVsb2NzLmRmJGlkWzFdCiAgcm93Lm5hbWVzKHJlbG9jc19kaXN0KSA8LSBuYW1lCiAgcmVsb2NzX3VuaXRzIDwtIGdyaWQudGV4dChwYXN0ZShyb3VuZChyZWxvY3NfZGlzdCwyKSwibSIpLCB4PTAuOSwgeT0wLjksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncD1ncGFyKGZvbnRmYWNlPTMsIGNvbD0iYmxhY2siLCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQogIHJlbG9jLnBsb3QgPC0gZ2dwbG90KCkgKyB0aGVtZV9jbGFzc2ljKCkgKyBnZW9tX3BhdGgoZGF0YT1yZWxvY3MuZGYsIGFlcyh4PXgseT15KSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gInJlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJvdyA9IGFycm93KGxlbmd0aD11bml0KC41LCJjbSIpLCBhbmdsZSA9IDIwLCBlbmRzPSJsYXN0IiwgdHlwZSA9ICJjbG9zZWQiKSkgKwogICAgZ2VvbV9wb2ludChkYXRhPXJlbG9jcy5kZiwgYWVzKHg9eCwgeT15KSkgKyBnZW9tX3BvaW50KGRhdGE9cmVsb2NzLmRmLCBhZXMoeD14WzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeT15WzFdKSwgc2l6ZSA9IDMsIGNvbG9yID0gImRhcmtncmVlbiIsIHBjaD0wKSArCiAgICBsYWJzKHg9IkVhc3RpbmcgKG0pIiwgeT0iTm9ydGhpbmcgKG0pIiwgdGl0bGU9cmVsb2NzLmRmJGlkWzFdKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSkgKwogICAgYW5ub3RhdGlvbl9jdXN0b20ocmVsb2NzX3VuaXRzKQogIHJlbG9jLnBsb3QKfQpgYGAKCgpGdW5jdGlvbiBvZiBkaXN0YW5jZSBvZiB0aW1lCmBgYHtyfQpkaXN0X2FuYWx5c2lzIDwtIGZ1bmN0aW9uKGZpbGVuYW1lKXsKICByZWxvY3NfZGF0YSA8LSByZWFkLmNzdihmaWxlID0gZmlsZW5hbWUpCiAgcmVsb2NzIDwtIGFzLmx0cmFqKGNiaW5kKHJlbG9jc19kYXRhJEVBU1RJTkcsIHJlbG9jc19kYXRhJE5PUlRISU5HKSxpZD1yZWxvY3NfZGF0YSRMSVpBUkROVU1CRVIsIHR5cGVJSSA9IEZBTFNFLCBkYXRlPU5VTEwpCiAgcmVsb2NzLmRmIDwtIGxkKHJlbG9jcykKICByZWxvY3NfZGlzdCA8LSBhcy5kYXRhLmZyYW1lKHN1bShzYXBwbHkocmVsb2NzLmRmJGRpc3QsIHN1bSwgbmEucm09VFJVRSkpKQogIGNvbG5hbWVzKHJlbG9jc19kaXN0KSA8LSAiVG90YWwgRGlzdGFuY2UiCiAgbmFtZSA8LSByZWxvY3MuZGYkaWRbMV0KICByb3cubmFtZXMocmVsb2NzX2Rpc3QpIDwtIG5hbWUKICB3cml0ZS50YWJsZShyZWxvY3NfZGlzdCxmaWxlPSJyZWxvY19kaXN0LmNzdiIsCiAgICAgICAgICAgICAgYXBwZW5kPVRSVUUsc2VwPSIsIiwgY29sLm5hbWVzPUZBTFNFLCByb3cubmFtZXM9VFJVRSkKICBkaXN0LnBsb3QKfQpgYGAKCgpNYXAgb2YgeWVhcmx5IEhSIHNoaWZ0cyBvZiBhIHN1YnNldCBvZiBHaWxhIE1vbnN0ZXJzLiBJbmNsdWRlcyBydW5uaW5nIE1DUCBwb2x5Z29ucywgRm9ydGlmeSBtY3AgcG9seWdvbnMgZm9yIGdncGxvdDIgYnkgWUVBUgpgYGB7cn0KTTIxNV9tY3AuMTE8LW1jcF9hbmFseXNpcy5QT0xZKCIuL00yMTUvMjAxMSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpNMjE1X21jcC4xMjwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vTTIxNS8yMDEyIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxMDRfbWNwLjA4PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTA0LzIwMDggLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjEwNF9tY3AuMDk8LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxMDQvMjAwOSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTE0X21jcC4wODwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjExNC8yMDA4IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxMTRfbWNwLjA5PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTE0LzIwMDkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjExNF9tY3AuMTA8LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxMTQvMjAxMCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTE0X21jcC4xMTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjExNC8yMDExIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxMTRfbWNwLjEyPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTE0LzIwMTIgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjEzN19tY3AuMDk8LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxMzcvMjAwOSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTM3X21jcC4xMDwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjEzNy8yMDEwIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxMzdfbWNwLjExPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTM3LzIwMTEgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjE0N19tY3AuMDk8LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxNDcvMjAwOSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTQ3X21jcC4xMDwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjE0Ny8yMDEwIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxNDdfbWNwLjExPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTQ3LzIwMTEgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjE0N19tY3AuMTI8LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxNDcvMjAxMiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMzZfbWNwLjA4PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvMjAwOCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMzZfbWNwLjA5PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvMjAwOSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMzZfbWNwLjEwPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvMjAxMCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMzZfbWNwLjExPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvMjAxMSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMzZfbWNwLjEyPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvMjAxMiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGNjZfbWNwLjA4PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvMjAwOCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGNjZfbWNwLjA5PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvMjAwOSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGNjZfbWNwLjEwPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvMjAxMCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpNMTE5X21jcC4wODwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vTTExOS8yMDA4IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCk0xMTlfbWNwLjA5PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NMTE5LzIwMDkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKTTExOV9tY3AuMTA8LW1jcF9hbmFseXNpcy5QT0xZKCIuL00xMTkvMjAxMCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpNMTEyX21jcC4wNzwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vTTExMi8yMDA3IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCk0xMTJfbWNwLjA5PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NMTEyLzIwMDkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKTTExMl9tY3AuMTA8LW1jcF9hbmFseXNpcy5QT0xZKCIuL00xMTIvMjAxMCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpNNjlfbWNwLjA5PC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NNjkvMjAwOSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpNNjlfbWNwLjEwPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NNjkvMjAxMCAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQoKIyMgRm9ydGlmeSBtY3AgcG9seWdvbnMgZm9yIGdncGxvdDIgKllFQVIqOgoKRjEwNF9tY3AuMDhUIDwtIGZvcnRpZnkoRjEwNF9tY3AuMDgsIHJlZ2lvbiA9ICJpZCIpCkYxMDRfbWNwLjA5VCA8LSBmb3J0aWZ5KEYxMDRfbWNwLjA5LCByZWdpb24gPSAiaWQiKQpGMTE0X21jcC4wOFQgPC0gZm9ydGlmeShGMTE0X21jcC4wOCwgcmVnaW9uID0gImlkIikKRjExNF9tY3AuMDlUIDwtIGZvcnRpZnkoRjExNF9tY3AuMDksIHJlZ2lvbiA9ICJpZCIpCkYxMTRfbWNwLjEwVCA8LSBmb3J0aWZ5KEYxMTRfbWNwLjEwLCByZWdpb24gPSAiaWQiKQpGMTE0X21jcC4xMVQgPC0gZm9ydGlmeShGMTE0X21jcC4xMSwgcmVnaW9uID0gImlkIikKRjExNF9tY3AuMTJUIDwtIGZvcnRpZnkoRjExNF9tY3AuMTIsIHJlZ2lvbiA9ICJpZCIpCkYxMzdfbWNwLjA5VCA8LSBmb3J0aWZ5KEYxMzdfbWNwLjA5LCByZWdpb24gPSAiaWQiKQpGMTM3X21jcC4xMFQgPC0gZm9ydGlmeShGMTM3X21jcC4xMCwgcmVnaW9uID0gImlkIikKRjEzN19tY3AuMTFUIDwtIGZvcnRpZnkoRjEzN19tY3AuMTEsIHJlZ2lvbiA9ICJpZCIpCkYxNDdfbWNwLjA5VCA8LSBmb3J0aWZ5KEYxNDdfbWNwLjA5LCByZWdpb24gPSAiaWQiKQpGMTQ3X21jcC4xMFQgPC0gZm9ydGlmeShGMTQ3X21jcC4xMCwgcmVnaW9uID0gImlkIikKRjE0N19tY3AuMTFUIDwtIGZvcnRpZnkoRjE0N19tY3AuMTEsIHJlZ2lvbiA9ICJpZCIpCkYxNDdfbWNwLjEyVCA8LSBmb3J0aWZ5KEYxNDdfbWNwLjEyLCByZWdpb24gPSAiaWQiKQpGMzZfbWNwLjA4VCA8LSBmb3J0aWZ5KEYzNl9tY3AuMDgsIHJlZ2lvbiA9ICJpZCIpCkYzNl9tY3AuMDlUIDwtIGZvcnRpZnkoRjM2X21jcC4wOSwgcmVnaW9uID0gImlkIikKRjM2X21jcC4xMFQgPC0gZm9ydGlmeShGMzZfbWNwLjEwLCByZWdpb24gPSAiaWQiKQpGMzZfbWNwLjExVCA8LSBmb3J0aWZ5KEYzNl9tY3AuMTEsIHJlZ2lvbiA9ICJpZCIpCkYzNl9tY3AuMTJUIDwtIGZvcnRpZnkoRjM2X21jcC4xMiwgcmVnaW9uID0gImlkIikKRjY2X21jcC4wOFQgPC0gZm9ydGlmeShGNjZfbWNwLjA4LCByZWdpb24gPSAiaWQiKQpGNjZfbWNwLjA5VCA8LSBmb3J0aWZ5KEY2Nl9tY3AuMDksIHJlZ2lvbiA9ICJpZCIpCkY2Nl9tY3AuMTBUIDwtIGZvcnRpZnkoRjY2X21jcC4xMCwgcmVnaW9uID0gImlkIikKTTExOV9tY3AuMDhUIDwtIGZvcnRpZnkoTTExOV9tY3AuMDgsIHJlZ2lvbiA9ICJpZCIpCk0xMTlfbWNwLjA5VCA8LSBmb3J0aWZ5KE0xMTlfbWNwLjA5LCByZWdpb24gPSAiaWQiKQpNMTE5X21jcC4xMFQgPC0gZm9ydGlmeShNMTE5X21jcC4xMCwgcmVnaW9uID0gImlkIikKTTExMl9tY3AuMDdUIDwtIGZvcnRpZnkoTTExMl9tY3AuMDcsIHJlZ2lvbiA9ICJpZCIpCk0xMTJfbWNwLjA5VCA8LSBmb3J0aWZ5KE0xMTJfbWNwLjA5LCByZWdpb24gPSAiaWQiKQpNMTEyX21jcC4xMFQgPC0gZm9ydGlmeShNMTEyX21jcC4xMCwgcmVnaW9uID0gImlkIikKTTY5X21jcC4wOVQgPC0gZm9ydGlmeShNNjlfbWNwLjA5LCByZWdpb24gPSAiaWQiKQpNNjlfbWNwLjEwVCA8LSBmb3J0aWZ5KE02OV9tY3AuMTAsIHJlZ2lvbiA9ICJpZCIpCk0yMTVfbWNwLjExVCA8LSBmb3J0aWZ5KE0yMTVfbWNwLjExLCByZWdpb24gPSAiaWQiKQpNMjE1X21jcC4xMlQgPC0gZm9ydGlmeShNMjE1X21jcC4xMiwgcmVnaW9uID0gImlkIikKCgptY3Auc2hpZnQuVEVTVDQgPC0gZ2dwbG90KCkgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9RjEwNF9tY3AuMDhULCBhZXMoeD1GMTA0X21jcC4wOFQkbG9uZywgeT1GMTA0X21jcC4wOFQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9MikgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9RjEwNF9tY3AuMDlULCBhZXMoeD1GMTA0X21jcC4wOVQkbG9uZywgeT1GMTA0X21jcC4wOVQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9MikgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMTRfbWNwLjA4VCwgYWVzKHg9RjExNF9tY3AuMDhUJGxvbmcsIHk9RjExNF9tY3AuMDhUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsYWNrIixsaW5ldHlwZT0zKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjExNF9tY3AuMDlULCBhZXMoeD1GMTE0X21jcC4wOVQkbG9uZywgeT1GMTE0X21jcC4wOVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTMpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTE0X21jcC4xMFQsIGFlcyh4PUYxMTRfbWNwLjEwVCRsb25nLCB5PUYxMTRfbWNwLjEwVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9MykgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMTRfbWNwLjExVCwgYWVzKHg9RjExNF9tY3AuMTFUJGxvbmcsIHk9RjExNF9tY3AuMTFUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsYWNrIixsaW5ldHlwZT0zKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjExNF9tY3AuMTJULCBhZXMoeD1GMTE0X21jcC4xMlQkbG9uZywgeT1GMTE0X21jcC4xMlQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTMpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTM3X21jcC4wOVQsIGFlcyh4PUYxMzdfbWNwLjA5VCRsb25nLCB5PUYxMzdfbWNwLjA5VCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJicm93biIsbGluZXR5cGU9NCkgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMzdfbWNwLjEwVCwgYWVzKHg9RjEzN19tY3AuMTBUJGxvbmcsIHk9RjEzN19tY3AuMTBUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJyb3duIixsaW5ldHlwZT00KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjEzN19tY3AuMTFULCBhZXMoeD1GMTM3X21jcC4xMVQkbG9uZywgeT1GMTM3X21jcC4xMVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYnJvd24iLGxpbmV0eXBlPTQpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTQ3X21jcC4wOVQsIGFlcyh4PUYxNDdfbWNwLjA5VCRsb25nLCB5PUYxNDdfbWNwLjA5VCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJyZWQiLGxpbmV0eXBlPTEpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTQ3X21jcC4xMFQsIGFlcyh4PUYxNDdfbWNwLjEwVCRsb25nLCB5PUYxNDdfbWNwLjEwVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJyZWQiLGxpbmV0eXBlPTEpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTQ3X21jcC4xMVQsIGFlcyh4PUYxNDdfbWNwLjExVCRsb25nLCB5PUYxNDdfbWNwLjExVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJyZWQiLGxpbmV0eXBlPTEpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTQ3X21jcC4xMlQsIGFlcyh4PUYxNDdfbWNwLjEyVCRsb25nLCB5PUYxNDdfbWNwLjEyVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJyZWQiLGxpbmV0eXBlPTEpICsKICAjIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuMDhULCBhZXMoeD1GMzZfbWNwLjA4VCRsb25nLCB5PUYzNl9tY3AuMDhUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTYpICsKICAjIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuMDlULCBhZXMoeD1GMzZfbWNwLjA5VCRsb25nLCB5PUYzNl9tY3AuMDlUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTYpICsKICAjIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuMTBULCBhZXMoeD1GMzZfbWNwLjEwVCRsb25nLCB5PUYzNl9tY3AuMTBUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTYpICsKICAjIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuMTFULCBhZXMoeD1GMzZfbWNwLjExVCRsb25nLCB5PUYzNl9tY3AuMTFUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTYpICsKICAjIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuMTJULCBhZXMoeD1GMzZfbWNwLjEyVCRsb25nLCB5PUYzNl9tY3AuMTJUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTYpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GNjZfbWNwLjA4VCwgYWVzKHg9RjY2X21jcC4wOFQkbG9uZywgeT1GNjZfbWNwLjA4VCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJncmVlbiIsbGluZXR5cGU9NSkgKwogIGdlb21fcG9seWdvbihkYXRhPUY2Nl9tY3AuMDlULCBhZXMoeD1GNjZfbWNwLjA5VCRsb25nLCB5PUY2Nl9tY3AuMDlUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImdyZWVuIixsaW5ldHlwZT01KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjY2X21jcC4xMFQsIGFlcyh4PUY2Nl9tY3AuMTBUJGxvbmcsIHk9RjY2X21jcC4xMFQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iZ3JlZW4iLGxpbmV0eXBlPTUpICsKICBnZW9tX3BvbHlnb24oZGF0YT1NMTE5X21jcC4wOFQsIGFlcyh4PU0xMTlfbWNwLjA4VCRsb25nLCB5PU0xMTlfbWNwLjA4VCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibHVlIixsaW5ldHlwZT02KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9TTExOV9tY3AuMDlULCBhZXMoeD1NMTE5X21jcC4wOVQkbG9uZywgeT1NMTE5X21jcC4wOVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmx1ZSIsbGluZXR5cGU9NikgKwogIGdlb21fcG9seWdvbihkYXRhPU0xMTlfbWNwLjEwVCwgYWVzKHg9TTExOV9tY3AuMTBUJGxvbmcsIHk9TTExOV9tY3AuMTBUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsdWUiLGxpbmV0eXBlPTYpICsKICBnZW9tX3BvbHlnb24oZGF0YT1NMTEyX21jcC4wN1QsIGFlcyh4PU0xMTJfbWNwLjA3VCRsb25nLCB5PU0xMTJfbWNwLjA3VCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJwdXJwbGUiLGxpbmV0eXBlPTIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1NMTEyX21jcC4wOVQsIGFlcyh4PU0xMTJfbWNwLjA5VCRsb25nLCB5PU0xMTJfbWNwLjA5VCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJwdXJwbGUiLGxpbmV0eXBlPTIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1NMTEyX21jcC4xMFQsIGFlcyh4PU0xMTJfbWNwLjEwVCRsb25nLCB5PU0xMTJfbWNwLjEwVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJwdXJwbGUiLGxpbmV0eXBlPTIpICsKICAjIGdlb21fcG9seWdvbihkYXRhPU02OV9tY3AuMDlULCBhZXMoeD1NNjlfbWNwLjA5VCRsb25nLCB5PU02OV9tY3AuMDlUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siKSArCiAgIyBnZW9tX3BvbHlnb24oZGF0YT1NNjlfbWNwLjEwVCwgYWVzKHg9TTY5X21jcC4xMFQkbG9uZywgeT1NNjlfbWNwLjEwVCRsYXQpLAogICMgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsYWNrIikgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9TTIxNV9tY3AuMTFULCBhZXMoeD1NMjE1X21jcC4xMVQkbG9uZywgeT1NMjE1X21jcC4xMVQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIpICsKICAjIGdlb21fcG9seWdvbihkYXRhPU0yMTVfbWNwLjEyVCwgYWVzKHg9TTIxNV9tY3AuMTJUJGxvbmcsIHk9TTIxNV9tY3AuMTJUJGxhdCksCiAgIyAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siKSArCiAgdGhlbWVfYncoKSArbGFicyh4PSJFYXN0aW5nIChtKSIsIHk9Ik5vcnRoaW5nIChtKSIpICsKICBsYWJzKGNhcHRpb24gPSAiRmlndXJlIDUgIHwgIFNDIFllYXJseSBob21lIHJhbmdlIHNoaWZ0cyBvZiA4IGxpemFyZHMsIGJvdGggbWFsZXMgYW5kIGZlbWFsZXMuIEhvbWUgcmFuZ2Ugc2hpZnRzIGFwcGVhciB0byBiZSBcbiByZWxhdGl2bGV5IHN0YWJsZSBvdmVyIHN0dWR5IHllYXJzLiIpKwogIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAsbGluZWhlaWdodCA9IDAuOSkpCiAgIyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSkKIyMgd2l0aGluIGVhY2ggZ2VvbV9wb2x5Z29uIGxpbmU/OgojIyBhZXMoY29sb3VyPSJyZWQib3IiTTExMl9tY3AuMDlUIikuLi4rc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsYnJlYWtzPWMoIiIsIiIsLi4uIiIpKSsKIyMgdmFsdWVzPWMoIiI9IiIsLi4uKQoKbWNwLnNoaWZ0LlRFU1Q0CmBgYAoKCgoKClJhdyBncm91cCAxMDAlIE1DUCBob21lIHJhbmdlIG1lYW5zIG9mIFN0b25lIENhbnlvbiBhbmQgT3dsIEhlYWQgQnV0dGVzLiBHcm91cGVkIGJ5IGVudmlyb25tZW50IGFuZCBzZXgKYGBge3J9CmxpYnJhcnkoUm1pc2MpCllSX0dSUF9NZWFucyA8LSBzdW1tYXJ5U0UoeWVhciwgbWVhc3VyZXZhcj0iSG9tZV9SYW5nZV8xMDBtY3AiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwdmFycz1jKCJFbnZpcm9ubWVudCIsIlNleCIpLG5hLnJtID0gVFJVRSkKCmthYmxlKFlSX0dSUF9NZWFucywgZm9ybWF0ID0gInBhbmRvYyIsIAogICAgICBjYXB0aW9uID0gJ1RhYmxlIDEgfCBSYXcgZ3JvdXAgMTAwJSBNQ1AgaG9tZSByYW5nZSBtZWFucyBvZiBTdG9uZSBDYW55b24gYW5kIE93bCBIZWFkIEJ1dHRlcy4gR3JvdXBlZCBieSBlbnZpcm9ubWVudCBhbmQgc2V4LicpCmBgYAoKCgoKUmF3IGdyb3VwIDk1JSBNQ1AgaG9tZSByYW5nZSBtZWFucyBvZiBTdG9uZSBDYW55b24gYW5kIE93bCBIZWFkIEJ1dHRlcy4gR3JvdXBlZCBieSBlbnZpcm9ubWVudCBhbmQgc2V4CmBgYHtyfQpZUl9HUlBfTWVhbnM5NSA8LSBzdW1tYXJ5U0UoeWVhciwgbWVhc3VyZXZhcj0iSG9tZV9SYW5nZV85NW1jcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cHZhcnM9YygiRW52aXJvbm1lbnQiLCJTZXgiKSxuYS5ybSA9IFRSVUUpCgprYWJsZShZUl9HUlBfTWVhbnM5NSwgZm9ybWF0ID0gInBhbmRvYyIsIGNhcHRpb24gPSAnVGFibGUgMiB8IFJhdyBncm91cCA5NSUgTUNQIGhvbWUgcmFuZ2UgbWVhbnMgb2YgcmF3IGRhdGEgb2YgU3RvbmUgQ2FueW9uIGFuZCBPd2wgSGVhZCBCdXR0ZXMuIEdyb3VwZWQgYnkgZW52aXJvbm1lbnQgYW5kIHNleC4nKQpgYGAKCgoKClJNLUFOT1ZBIGZvciAxMDAlIE1DUCBhbmFseXNlcyBiZXR3ZWVuIHRoZSBzdWJzaWRpemVkIGFuZCBub24tc3Vic2lkaXplZApgYGB7cn0KIyBHZXQgcC12YWx1ZXMgZnJvbSBtaXhlZCBtb2RlbCBGIHZhbHVlczoKbGlicmFyeShsbWU0KQpsaWJyYXJ5KHJlYWRyKQp5ZWFyIDwtIHJlYWRfY3N2KCJHTV9Db25zb2xpZGF0ZWRfQnlZZWFyLmNzdiIpCgpSTW1vZC55ZWFyPC1sbWVyKEhvbWVfUmFuZ2VfMTAwbWNwfkVudmlyb25tZW50K1llYXIrU2V4K04xMDArRW52aXJvbm1lbnQqU2V4KwogICAgICAgICAgICAgICAgICAgKDF8R2lsYSksZGF0YSA9IHllYXIpCnN1bW1hcnkoUk1tb2QueWVhcikKYGBgCgoKQU5PVkEgdGFibGUgZm9yIDEwMCUgTUNQcyBiZXR3ZWVuIHRoZSB0d28gcG9wdWxhdGlvbnMKYGBge3J9CmFub3ZhKFJNbW9kLnllYXIpCmBgYAoKCgoKClJNLUFOT1ZBIGZvciA5NSUgTUNQIGFuYWx5c2VzIGJldHdlZW4gdGhlIHN1YnNpZGl6ZWQgYW5kIG5vbi1zdWJzaWRpemVkCmBgYHtyfQpSTW1vZC55ZWFyOTU8LWxtZXIoSG9tZV9SYW5nZV85NW1jcH5FbnZpcm9ubWVudCtZZWFyK1NleCtOMTAwK0Vudmlyb25tZW50KlNleCsKICAgICAgICAgICAgICAgICAgICgxfEdpbGEpLGRhdGEgPSB5ZWFyKQpzdW1tYXJ5KFJNbW9kLnllYXI5NSkKYGBgCgoKQU5PVkEgdGFibGUgZm9yIDk1JSBNQ1BzIGJldHdlZW4gdGhlIHR3byBwb3B1bGF0aW9ucwpgYGB7cn0KYW5vdmEoUk1tb2QueWVhcjk1KQpgYGAKCgoKCgpSYXcgZ3JvdXAgbWVhbnMgQU5EIGFkanVzdGVkIEVNTXMgb2YgWWVhcmx5IE92ZXJhbGwgMTAwJU1DUApgYGB7cn0KUk1tb2QueWVhcjEwMDwtbG1lcihIb21lX1JhbmdlXzEwMG1jcH5FbnZpcm9ubWVudCtZZWFyK1NleCtOMTAwK0Vudmlyb25tZW50KlNleCsoMXxHaWxhKSxkYXRhID0geWVhcikKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIEVNTXMgYWRqdXN0ZWQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKClJNLm1hcmdpbmFsIDwtIGxzbWVhbnMoUk1tb2QueWVhcjEwMCwgCiAgICAgICAgICAgICAgICAgICAgfiBFbnZpcm9ubWVudCkKCiMjIENBVEFHT1JJWkUgTFNNIEdSQVBIIEJZIFNFWCBCRVRXRUVOIEVOVklST05NRU5UOgpyZWZSTV9zZXggPC0gbHNtZWFucyhSTW1vZC55ZWFyMTAwLCBzcGVjcyA9IGMoIkVudmlyb25tZW50IiwiU2V4IikpCgojIHJlZlJNX3NleApyZWZfZGZSTV9zZXggPC0gYXMuZGF0YS5mcmFtZShzdW1tYXJ5KHJlZlJNX3NleCkpCnBkX1JNIDwtIHBvc2l0aW9uX2RvZGdlKDAuMSkKCnlyLm1lYW4uYWRqPC1nZ3Bsb3QocmVmX2RmUk1fc2V4LCBhZXMoeD1TZXgseT1sc21lYW4sZ3JvdXA9RW52aXJvbm1lbnQpKSsKICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IGZhY3RvcihFbnZpcm9ubWVudCkpLCBzaXplID0gNCxwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguMSksIAogICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFKSsKICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzPWMoMSwgMikpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bHNtZWFuLVNFLCB5bWF4PWxzbWVhbitTRSksIHdpZHRoPS4xLHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCkpKwogIGdlb21fbGluZShwb3NpdGlvbj1wZF9STSkgKwogIHRoZW1lX2J3KCkgICsKICB4bGFiKCIiKSArCiAgeWxhYigiIikgKwogICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKC44NywuODUpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnkgID0gZWxlbWVudF90ZXh0KHZqdXN0PTAuNSwgc2l6ZT04KSwKICAgICAgICBheGlzLnRpdGxlLnkgID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLAogICAgICAgIGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpIAoKeXIubWVhbi5hZGoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFJhdyBHcm91cCBNZWFucyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgcGRfUk0gPC0gcG9zaXRpb25fZG9kZ2UoMC4xKQoKUmF3LlllYXJIUjwtZ2dwbG90KFlSX0dSUF9NZWFucywgYWVzKHg9U2V4LHk9SG9tZV9SYW5nZV8xMDBtY3AsZ3JvdXA9RW52aXJvbm1lbnQpKSsKICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IGZhY3RvcihFbnZpcm9ubWVudCkpLCBzaXplID0gNCxwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSguMSkpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49SG9tZV9SYW5nZV8xMDBtY3Atc2UsIHltYXg9SG9tZV9SYW5nZV8xMDBtY3Arc2UpLAogICAgICAgICAgICAgICAgd2lkdGg9LjEscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkrCiAgZ2VvbV9saW5lKHBvc2l0aW9uPXBkX1JNKSArCiAgdGhlbWVfYncoKSsKICB4bGFiKCIiKSsKICB5bGFiKCIxMDAlIE1DUCBBcmVhIChoYSkiKSArCiAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoLjg3LC44NSksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRleHQueSAgPSBlbGVtZW50X3RleHQodmp1c3Q9MC41LCBzaXplPTgpLAogICAgICAgIGF4aXMudGl0bGUueSAgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksCiAgICAgICAgYXhpcy50aXRsZS54ICA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgCgoKUmF3LlllYXJIUjwtUmF3LlllYXJIUiArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb249YygwLDEpLAogICAgICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb249YygwLjA1LCAwLjk1KSwKICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siKSkgKwogICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShuYW1lICA9IiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoIm5vbnN1YnNpZGl6ZWQiLCAic3Vic2lkaXplZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJOb25zdWJzaWRpemVkIiwgIlN1YnNpZGl6ZWQiKSkKClJhdy5ZZWFySFIKCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShncmlkKQoKIyBncmlkLmFycmFuZ2UoUmF3LlllYXJIUiwgeXIubWVhbi5hZGosIG5yb3cgPSAxLCAgCiMgICAgICAgICAgICAgIGJvdHRvbSA9IHRleHRHcm9iKCJGaWd1cmUgNSB8IGEuIFJhdyBncm91cCBtZWFucyBvZiBvdmVyYWxsIHllYXJseSBob21lIHJhbmdlcyBiZXR3ZWVuIG1hbGVzIGFuZCBmZW1hbGVzLiBOb3RlIHRoYXQgdGhlIG1hbGUgXG4gaG9tZSByYW5nZSBvZiB0aGUgc3Vic2lkaXplZCBwb3B1bGF0aW9uIGlzIHNtYWxsZXIgdGhhbiB0aGF0IG9mIHRoZSBmZW1hbGUgaG9tZSByYW5nZSBpbiB0aGUgbm9uLXN1YnNpZGl6ZWQgXG4gcG9wdWxhdGlvbi4gYi4gR3JvdXAgbWVhbnMgb2YgaG9tZSByYW5nZXMgYWZ0ZXIgYmVpbmcgYWRqdXN0ZWQgZm9yIGVudmlyb25tZW50LCB5ZWFyLCBzZXgsIGFuZCBzYW1wbGUgc2l6ZS4iLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncCA9IGdwYXIoZm9udGZhY2UgPSAxLGZvbnRzaXplID0gMTApLGhqdXN0ID0gMCwgeCA9IDApKQoKIyBncmlkLmFycmFuZ2UoUmF3LlllYXJIUiwgeXIubWVhbi5hZGosIG5yb3cgPSAxKQojIGdyaWQuYXJyYW5nZShSYXcuWWVhckhSLCB5ci5tZWFuLmFkaiwgbnJvdyA9IDEpCiMgZ2dhcnJhbmdlKFJhdy5ZZWFySFIsIHlyLm1lYW4uYWRqLCBsYWJlbHMgPSBjKCJBIiwgIkIiKSwKIyAgICAgICAgICAgbmNvbCA9IDIpCmBgYAoKCgoKCgpEaXJlY3Rpb25hbCBtZWFucyBvZiBob21lIHJhbmdlICgxMDAlIE1DUCkgYWZ0ZXIgYmVpbmcgYWRqdXN0ZWQgZm9yIHllYXIsIHNleCBhbmQgc2FtcGxlIHNpemUKYGBge3J9CmthYmxlKHJlZl9kZlJNX3NleCwgZm9ybWF0ID0gInBhbmRvYyIsIGNhcHRpb24gPSAnVGFibGUgfCBEaXJlY3Rpb25hbCBtZWFucyBvZiBob21lIHJhbmdlICgxMDAlIE1DUCkgYWZ0ZXIgYmVpbmcgYWRqdXN0ZWQgZm9yIHllYXIsIHNleCBhbmQgc2FtcGxlIHNpemUuJykKYGBgCgoKCgpSTS1BTk9WQSBvZiA5NSUgS0RFcyBmb3IgdGhlIHN1YnNpZGl6ZWQgcG9wdWxhdGlvbgpgYGB7cn0KUk0uS0RFbW9kLnllYXI8LWxtZXIoSG9tZV9SYW5nZV85NWtkZX5ZZWFyK1NleCtOKygxfEdpbGEpLGRhdGEgPSBzdWIpCgpzdW1tYXJ5KFJNLktERW1vZC55ZWFyKQpgYGAKCkFOT1ZBIFRhYmxlIGZvciA5NSVLREUKYGBge3J9CmFub3ZhKFJNLktERW1vZC55ZWFyKQpgYGAKCgoKClJNLUFOT1ZBIG9mIDUwJSBLREVzIGZvciB0aGUgc3Vic2lkaXplZApgYGB7cn0KUk0uS0RFLjUwLm1vZC55ZWFyPC1sbWVyKEhvbWVfUmFuZ2VfNTBrZGV+WWVhcitTZXgrTisoMXxHaWxhKSxkYXRhID0gc3ViKQoKc3VtbWFyeShSTS5LREUuNTAubW9kLnllYXIpCmBgYAoKQU5PVkEgVGFsYmUgb2YgNTAlICBLREUgZm9yIHRoZSBzdWJzaWRpemVkCmBgYHtyfQphbm92YShSTS5LREUuNTAubW9kLnllYXIpCmBgYAoKCgoKVEFCTEUuIFJhdyBHcm91cCA1MCUgS0RFIGhvbWUgcmFuZ2UgbWVhbnMgbWFsZSBhbmQgZmVtYWxlIGhvbWUgcmFuZ2VzIGF0IFN0b25lIENhbnlvbgpgYGB7cn0KWVJfR1JQX01lYW5zLjUwS0RFIDwtIHN1bW1hcnlTRShzdWIsIG1lYXN1cmV2YXI9IkhvbWVfUmFuZ2VfNTBrZGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXB2YXJzPWMoIlNleCIpLG5hLnJtID0gVFJVRSkKCmthYmxlKFlSX0dSUF9NZWFucy41MEtERSwgZm9ybWF0ID0gInBhbmRvYyIsIGNhcHRpb24gPSAnVGFibGUgNSB8IFJhdyBHcm91cCA1MCUgS0RFIGhvbWUgcmFuZ2UgbWVhbnMgbWFsZSBhbmQgZmVtYWxlIGhvbWUgcmFuZ2VzIGF0IFN0b25lIENhbnlvbi4nKQpgYGAKCgoKClJhdyBncm91cCBtZWFucyBBTkQgYWRqdXN0ZWQgRU1NcyBvZiBZZWFybHkgT3ZlcmFsbCA5NSUgS0RFcyBiZXR3ZWVuIG5vbi9zdWJzaWRpemVkIHBvcHVsYXRpb25zCmBgYHtyfQpSTW1vZC45NWtkZTwtbG1lcihIb21lX1JhbmdlXzk1a2RlfkVudmlyb25tZW50K1llYXIrU2V4K04rRW52aXJvbm1lbnQqU2V4KygxfEdpbGEpLGRhdGEgPSB5ZWFyKQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBFTU1zIG9mIDk1JSBLREVzICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKUk0ubWFyZ2luYWwgPC0gbHNtZWFucyhSTW1vZC45NWtkZSwgCiAgICAgICAgICAgICAgICAgICAgICAgfiBFbnZpcm9ubWVudCkKCiMjIENBVEFHT1JJWkUgTFNNIEdSQVBIIEJZIFNFWCBCRVRXRUVOIEVOVklST05NRU5UOgpyZWZSTV9rZGUgPC0gbHNtZWFucyhSTW1vZC45NWtkZSwgc3BlY3MgPSBjKCJFbnZpcm9ubWVudCIsIlNleCIpKQoKIyByZWZSTV9zZXgKcmVmX2RmUk1fa2RlIDwtIGFzLmRhdGEuZnJhbWUoc3VtbWFyeShyZWZSTV9rZGUpKQojIHBkX1JNIDwtIHBvc2l0aW9uX2RvZGdlKDAuMSkKCmtkZS5tZWFuLmFkajwtZ2dwbG90KHJlZl9kZlJNX2tkZSwgYWVzKHg9U2V4LHk9bHNtZWFuLGdyb3VwPUVudmlyb25tZW50KSkrCiAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSBmYWN0b3IoRW52aXJvbm1lbnQpKSwgc2l6ZSA9IDQscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoLjEpLCAKICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UpKwogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXM9YygxLCAyKSkrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sc21lYW4tU0UsIHltYXg9bHNtZWFuK1NFKSwgd2lkdGg9LjEscG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkrCiAgZ2VvbV9saW5lKHBvc2l0aW9uPXBkX1JNKSArCiAgdGhlbWVfYncoKSsKICB4bGFiKCIiKSsKICB5bGFiKCIiKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKC44NywuODUpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQodmp1c3Q9MC41LCBzaXplPTE2KSwKICAgICAgICBheGlzLnRleHQueSAgPSBlbGVtZW50X3RleHQodmp1c3Q9MC41LCBzaXplPTgpLAogICAgICAgIGF4aXMudGl0bGUueSAgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksCiAgICAgICAgYXhpcy50aXRsZS54ICA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJGZW1hbGUiLCAiTWFsZSIpKSAKCmtkZS5tZWFuLmFkagoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyByYXcgRU1NcyBvZiA5NSUgS0RFcyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCiMgcGRfUk0gPC0gcG9zaXRpb25fZG9kZ2UoMC4xKQoKIyBnZW9tX2xpbmUocG9zaXRpb249cGQpKwoKUmF3LmtkZTwtZ2dwbG90KFlSX01lYW5zLjk1S0RFYWxsLCBhZXMoeD1TZXgseT1Ib21lX1JhbmdlXzk1a2RlLGdyb3VwPUVudmlyb25tZW50KSkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gZmFjdG9yKEVudmlyb25tZW50KSksIHNpemUgPSA0LHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKC4xKSwKICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPUhvbWVfUmFuZ2VfOTVrZGUtc2UsIHltYXg9SG9tZV9SYW5nZV85NWtkZStzZSksCiAgICAgICAgICAgICAgICB3aWR0aD0uMSwgcG9zaXRpb249cG9zaXRpb25fZG9kZ2UoKSkgKwogIGdlb21fbGluZShwb3NpdGlvbj1wZF9STSkgKwogIHRoZW1lX2J3KCkgKwogIHhsYWIoIiIpICsKICB5bGFiKCI5NSUgS0RFIEFyZWEgKGhhKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKC44NywuODUpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueCAgPSBlbGVtZW50X3RleHQodmp1c3Q9MC41LCBzaXplPTE2KSwKICAgICAgICBheGlzLnRleHQueSAgPSBlbGVtZW50X3RleHQodmp1c3Q9MC41LCBzaXplPTgpLAogICAgICAgIGF4aXMudGl0bGUueSAgPSBlbGVtZW50X3RleHQoc2l6ZT0xNiksCiAgICAgICAgYXhpcy50aXRsZS54ICA9IGVsZW1lbnRfdGV4dChzaXplPTEwKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJGZW1hbGUiLCAiTWFsZSIpKSAKClJhdy5rZGUKCiMgUmF3LmtkZTwtUmF3LmtkZSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb249YygwLDEpLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb249YygwLjA1LCAwLjk1KSwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siKSkgKwojICAgc2NhbGVfc2hhcGVfZGlzY3JldGUobmFtZSAgPSIiLAojICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoIm5vbnN1YnNpZGl6ZWQiLCAic3Vic2lkaXplZCIpLAojICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIk5vbnN1YnNpZGl6ZWQiLCAiU3Vic2lkaXplZCIpKQojIFJhdy5rZGUKCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGdyaWQpCgojIGdnYXJyYW5nZShSYXcua2RlLCBrZGUubWVhbi5hZGosIGxhYmVscyA9IGMoIkEiLCAiQiIpLAojICAgICAgICAgICBucm93ID0gMSkKCmBgYAoKCkNvbGxlY3RpdmUgZ3JpZCBvZiAxMDAlIE1DUCBhbmQgOTUlIEtERSBvZiBib3RoIHNpdGVzIGZyb20gYWJvdmUKYGBge3J9CmdnYXJyYW5nZShSYXcuWWVhckhSLCB5ci5tZWFuLmFkaiwgUmF3LmtkZSwga2RlLm1lYW4uYWRqLCBsYWJlbHMgPSBjKCJBIiwgIkIiLCAiQyIsIkQiKSwKICAgICAgICAgIG5jb2wgPSAyLCBucm93ID0gMikKYGBgCgoKCgo0My40IG1hbGUgNDIuOSBmZW1hbGUKWWVhcmx5IG92ZXJhbGwgbWVhbnMgb2YgOTUlIEtERXMgZ3JvdXBlZCBieSBzaXRlIGFuZCBzZXgKYGBge3J9CllSX01lYW5zLjk1S0RFYWxsIDwtIHN1bW1hcnlTRSh5ZWFyLCBtZWFzdXJldmFyPSJIb21lX1JhbmdlXzk1a2RlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwdmFycz1jKCJFbnZpcm9ubWVudCIsIlNleCIpLG5hLnJtID0gVFJVRSkKIAprYWJsZShZUl9NZWFucy45NUtERWFsbCwgZm9ybWF0ID0gInBhbmRvYyIsIGNhcHRpb24gPSAnVGFibGUgfCBSYXcgR3JvdXAgOTUlIEtERSBob21lIHJhbmdlIG1lYW5zIG1hbGUgYW5kIGZlbWFsZSBob21lIHJhbmdlcyBhdCBub24vc3Vic2lkaXplZC4nKQpgYGAKCgoKCgpQYWlyd2lzZSBDb21wYXJpc29ucywgYmV0d2VlbiBzZXhlcyBieSBlbnZpcm9ubWVudCwgYW5kIGJldHdlZW4gZW52aXJvbm1lbnRzIGF2ZXJhZ2VkIGFjcm9zcyBzZXgKYGBge3J9ClJNbW9kLnllYXIuRW08LWxtZXIoSG9tZV9SYW5nZV8xMDBtY3B+RW52aXJvbm1lbnQrWWVhcitTZXgrTjEwMCtFbnZpcm9ubWVudCpTZXgrCiAgICAgICAgICAgICAgICAgICAgICAoMXxHaWxhKSxkYXRhID0geWVhcikKCiMgUk1tb2QueWVhci5FbTk1PC1sbWVyKEhvbWVfUmFuZ2VfOTVtY3B+RW52aXJvbm1lbnQrWWVhcitTZXgrTjk1K0Vudmlyb25tZW50KlNleCsKIyAgICAgICAgICAgICAgICAgICAgICAgKDF8R2lsYSksZGF0YSA9IHllYXIpCgojIFNleC5lbW0ub2EgPC0gZW1tZWFucyhSTW1vZC55ZWFyLkVtLCBjKCJFbnZpcm9ubWVudCIsIlNleCIpKQojIHBhaXJzKFNleC5lbW0ub2EpCgplbW1fcy50MiA8LSBlbW1lYW5zKFJNbW9kLnllYXIuRW0sIHBhaXJ3aXNlIH4gU2V4IHwgRW52aXJvbm1lbnQpCmVtbV9zLnQyCiMgZW1tX3MuZTEgPC0gZW1tZWFucyhSTW1vZC55ZWFyLkVtLCBwYWlyd2lzZSB+IEVudmlyb25tZW50KQojIGVtbV9zLmUxCmBgYAoKCkdyYXBoaWNhbCBDb21wYXJpc29ucyBvZiBTZXggV2l0aGluIEVhY2ggRW52aXJvbm1lbnQ6CmBgYHtyfQpwbG90KGVtbV9zLnQyLCBjb21wYXJpc29ucyA9IFRSVUUsIHhsYWIgPSAiTGVhc3QgU3F1YXJlIE1lYW4gKGhhKSIsIHlsYWIgPSAiRW52aXJvbm1lbnQiKQpgYGAKCgoKClBhaXJ3aXNlIGJ5IHNleCBiZXR3ZWVuIGVudmlvcm5lbWVudHMgMTAwJSAgTUNQLCBhbmQgOTUlIEtERXMKYGBge3J9CmVtbV9zLnQzIDwtIGVtbWVhbnMoUk1tb2QueWVhci5FbSwgcGFpcndpc2UgfiBFbnZpcm9ubWVudCB8IFNleCkKZW1tX3MudDMKCiMgZW1tX3MudDk1IDwtIGVtbWVhbnMoUk1tb2QueWVhci5FbTk1LCBwYWlyd2lzZSB+IEVudmlyb25tZW50IHwgU2V4KQojIGVtbV9zLnQ5NQpgYGAKCgoKR3JhcGhpY2FsIENvbXBhcmlzb25zIG9mIFNleCBiZXR3ZWVuIHRoZSB0d28gcG9wdWxhdGlvbnM6CmBgYHtyfQpwbG90KGVtbV9zLnQzLCBjb21wYXJpc29ucyA9IFRSVUUsIHhsYWIgPSAiTGVhc3QgU3F1YXJlIE1lYW4gKGhhKSIsIHlsYWIgPSAiRW52aXJvbm1lbnQiKQpgYGAKCgoKCgpJbmVyYWN0aXZlIG1hcCBvZiBNQ1BzIGF0IFN0b25lIENhbnlvbgpgYGB7cn0KTTY3X01DUDwtbWNwX2FuYWx5c2lzLlBPTFkoJy4vTTY3L002NyAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQpNNjlfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9NNjkvTTY5IC5jc3YnLCBwZXJjZW50YWdlPSAxMDApCk0yNTVfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9NMjU1L00yNTUgLmNzdicsIHBlcmNlbnRhZ2U9IDEwMCkKTTIxNV9NQ1A8LW1jcF9hbmFseXNpcy5QT0xZKCcuL00yMTUvTTIxNSAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQpNMTRfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9NMTQvTTE0IC5jc3YnLCBwZXJjZW50YWdlPSAxMDApCk0xMTlfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9NMTE5L00xMTkgLmNzdicsIHBlcmNlbnRhZ2U9IDEwMCkKTTExMl9NQ1A8LW1jcF9hbmFseXNpcy5QT0xZKCcuL00xMTIvTTExMiAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQoKRjY2X01DUDwtbWNwX2FuYWx5c2lzLlBPTFkoJy4vRjY2L0Y2NiAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQpGMzZfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9GMzYvRjM2IC5jc3YnLCBwZXJjZW50YWdlPSAxMDApCkYyNTJfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9GMjUyL0YyNTIgLmNzdicsIHBlcmNlbnRhZ2U9IDEwMCkKRjIxNF9NQ1A8LW1jcF9hbmFseXNpcy5QT0xZKCcuL0YyMTQvRjIxNCAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQpGMjAwX01DUDwtbWNwX2FuYWx5c2lzLlBPTFkoJy4vRjIwMC9GMjAwIC5jc3YnLCBwZXJjZW50YWdlPSAxMDApCkYxNDdfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9GMTQ3L0YxNDcgLmNzdicsIHBlcmNlbnRhZ2U9IDEwMCkKRjE0Nl9NQ1A8LW1jcF9hbmFseXNpcy5QT0xZKCcuL0YxNDYvRjE0NiAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQpGMTM3X01DUDwtbWNwX2FuYWx5c2lzLlBPTFkoJy4vRjEzNy9GMTM3IC5jc3YnLCBwZXJjZW50YWdlPSAxMDApCkYxMzVfTUNQPC1tY3BfYW5hbHlzaXMuUE9MWSgnLi9GMTM1L0YxMzUgLmNzdicsIHBlcmNlbnRhZ2U9IDEwMCkKRjExNF9NQ1A8LW1jcF9hbmFseXNpcy5QT0xZKCcuL0YxMTQvRjExNCAuY3N2JywgcGVyY2VudGFnZT0gMTAwKQpGMTA0X01DUDwtbWNwX2FuYWx5c2lzLlBPTFkoJy4vRjEwNC9GMTA0IC5jc3YnLCBwZXJjZW50YWdlPSAxMDApCgpNYWxlLk1DUCA8LSByYmluZChNNjdfTUNQLE02OV9NQ1AsTTI1NV9NQ1AsTTIxNV9NQ1AsTTE0X01DUCxNMTE5X01DUCxNMTEyX01DUCkKRmVtYWxlLk1DUCA8LSByYmluZChGNjZfTUNQLEYzNl9NQ1AsRjI1Ml9NQ1AsRjIxNF9NQ1AsRjIwMF9NQ1AsRjE0N19NQ1AsRjE0Nl9NQ1AsRjEzN19NQ1AsCiAgICAgICAgICAgICAgICAgICAgRjEzNV9NQ1AsRjExNF9NQ1AsRjEwNF9NQ1ApCgptYXB2aWV3T3B0aW9ucyhiYXNlbWFwcyA9IGMoIk9wZW5TdHJlZXRNYXAiLCJFc3JpLldvcmxkSW1hZ2VyeSIsIk9wZW5Ub3BvTWFwIiksCiAgICAgICAgICAgICAgIG5hLmNvbG9yID0gIm1hZ2VudGEiLAogICAgICAgICAgICAgICBsYXllcnMuY29udHJvbC5wb3MgPSAidG9wbGVmdCIpCgptYXB2aWV3KE1hbGUuTUNQLCBsZWdlbmQ9RiwgemNvbD0iaWQiLCBjb2wucmVnaW9ucyA9IGMoImJsdWUiKSwgYWxwaGEucmVnaW9ucz0wLjMpICsgCiAgbWFwdmlldyhGZW1hbGUuTUNQLCBsZWdlbmQ9RiwgemNvbCA9ICJpZCIsIGNvbC5yZWdpb25zID0gYygicmVkIiksIGFscGhhLnJlZ2lvbnM9MC4zKQpgYGAKCgoKCgpDcmVhdGUgc3RhZ25hbnQgc3RhbWVuIG1hcCBvZiBNQ1BzIGF0IFN0b25lIENhbnlvbgpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KIyMgR2V0L3ZpZXcgdGhlIHN0YW1lbiBtYXAgKGJib3ggc2hvdWxkIGJlIGFkanVzdGVkIGFwcHJvcHJpYXRlbHkpOgpteU1hcCA8LSBnZXRfc3RhbWVubWFwKGJib3ggPSBjKGxlZnQgPSAtMTExLjAwOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3R0b20gPSAzMi40NTksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSAtMTEwLjk2OSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3AgPSAzMi40NzQpLAogICAgICAgICAgICAgICAgICAgICAgIG1hcHR5cGUgPSAidGVycmFpbiIsIAogICAgICAgICAgICAgICAgICAgICAgIGNyb3AgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICB6b29tID0gMTUpCgpGMTA0X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMTA0X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMTE0X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMTE0X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMTM1X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMTM1X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMTM3X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMTM3X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMTQ2X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMTQ2X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMTQ3X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMTQ3X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMjAwX2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMjAwX01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMjE0X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMjE0X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMjUyX2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGMjUyX01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpGMzZfbGF0bG9uIDwtIHNwVHJhbnNmb3JtKEYzNl9NQ1AsIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKSkKRjY2X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShGNjZfTUNQLCBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikpCk0xMTJfbGF0bG9uIDwtIHNwVHJhbnNmb3JtKE0xMTJfTUNQLCBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikpCk0xMTlfbGF0bG9uIDwtIHNwVHJhbnNmb3JtKE0xMTlfTUNQLCBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikpCk0xNF9sYXRsb24gPC0gc3BUcmFuc2Zvcm0oTTE0X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpNMjE1X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShNMjE1X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpNMjU1X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShNMjU1X01DUCwgQ1JTKCIrcHJvaj1sb25nbGF0ICtkYXR1bT1XR1M4NCIpKQpNNjdfbGF0bG9uIDwtIHNwVHJhbnNmb3JtKE02N19NQ1AsIENSUygiK3Byb2o9bG9uZ2xhdCArZGF0dW09V0dTODQiKSkKTTY5X2xhdGxvbiA8LSBzcFRyYW5zZm9ybShNNjlfTUNQLCBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikpCgpTQ19zdGFtZW5fbWFwIDwtIGdnbWFwKG15TWFwKSArCiAgIyBnZW9tX3BvaW50KGRhdGEgPSBwcm9qX2xhdC5sb24sIGFlcyh4PXgsIHk9eSksIHNpemUgPSAwLjMsIGFscGhhID0gMC44LCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGZvcnRpZnkoRjEwNF9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJyZWQiLCAKICAgICAgICAgICAgIGZpbGwgPSBOQSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gZm9ydGlmeShGMTE0X2xhdGxvbiksIGFlcyhsb25nLCBsYXQsIGdyb3VwPWdyb3VwKSwgY29sb3VyID0gInJlZCIsIAogICAgICAgICAgICAgICBmaWxsID0gTkEpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGZvcnRpZnkoRjEzNV9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJyZWQiLCAKICAgICAgICAgICAgICAgZmlsbCA9IE5BKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmb3J0aWZ5KEYxMzdfbGF0bG9uKSwgYWVzKGxvbmcsIGxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvdXIgPSAicmVkIiwgCiAgICAgICAgICAgICAgIGZpbGwgPSBOQSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gZm9ydGlmeShGMTQ2X2xhdGxvbiksIGFlcyhsb25nLCBsYXQsIGdyb3VwPWdyb3VwKSwgY29sb3VyID0gInJlZCIsIAogICAgICAgICAgICAgICBmaWxsID0gTkEpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGZvcnRpZnkoRjE0N19sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJyZWQiLCAKICAgICAgICAgICAgICAgZmlsbCA9IE5BKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmb3J0aWZ5KEYyMDBfbGF0bG9uKSwgYWVzKGxvbmcsIGxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvdXIgPSAicmVkIiwgCiAgICAgICAgICAgICAgIGZpbGwgPSBOQSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gZm9ydGlmeShGMjE0X2xhdGxvbiksIGFlcyhsb25nLCBsYXQsIGdyb3VwPWdyb3VwKSwgY29sb3VyID0gInJlZCIsIAogICAgICAgICAgICAgICBmaWxsID0gTkEpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGZvcnRpZnkoRjI1Ml9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJyZWQiLCAKICAgICAgICAgICAgICAgZmlsbCA9IE5BKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmb3J0aWZ5KEYzNl9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJyZWQiLCAKICAgICAgICAgICAgICAgZmlsbCA9IE5BKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmb3J0aWZ5KEY2Nl9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJyZWQiLCAKICAgICAgICAgICAgICAgZmlsbCA9IE5BKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmb3J0aWZ5KE0xMTJfbGF0bG9uKSwgYWVzKGxvbmcsIGxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvdXIgPSAiYmx1ZSIsIAogICAgICAgICAgICAgICBmaWxsID0gTkEpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGZvcnRpZnkoTTExOV9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJibHVlIiwgCiAgICAgICAgICAgICAgIGZpbGwgPSBOQSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gZm9ydGlmeShNMTRfbGF0bG9uKSwgYWVzKGxvbmcsIGxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvdXIgPSAiYmx1ZSIsIAogICAgICAgICAgICAgICBmaWxsID0gTkEpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGZvcnRpZnkoTTIxNV9sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJibHVlIiwgCiAgICAgICAgICAgICAgIGZpbGwgPSBOQSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gZm9ydGlmeShNMjU1X2xhdGxvbiksIGFlcyhsb25nLCBsYXQsIGdyb3VwPWdyb3VwKSwgY29sb3VyID0gImJsdWUiLCAKICAgICAgICAgICAgICAgZmlsbCA9IE5BKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBmb3J0aWZ5KE02N19sYXRsb24pLCBhZXMobG9uZywgbGF0LCBncm91cD1ncm91cCksIGNvbG91ciA9ICJibHVlIiwgCiAgICAgICAgICAgICAgIGZpbGwgPSBOQSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gZm9ydGlmeShNNjlfbGF0bG9uKSwgYWVzKGxvbmcsIGxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvdXIgPSAiYmx1ZSIsIAogICAgICAgICAgICAgICBmaWxsID0gTkEpICsKICB4bGFiKCJMb25naXR1ZGUiKSArCiAgeWxhYigiTGF0aXR1ZGUiKSAKCiMgU0Nfc3RhbWVuX21hcAoKbGlicmFyeShnZ3NuKQoKU0Nfc3RhbWVuX21hcDwtU0Nfc3RhbWVuX21hcCArIGdnc246OnNjYWxlYmFyKHgubWluID0gLTExMC45NzIsIHgubWF4ID0gLTExMC45NjYsCiAgICAgICAgICAgICAgICAgICAgIHkubWluID0gMzIuNDc0LCB5Lm1heCA9IDMyLjQ3NiwgCiAgICAgICAgICAgICAgICAgICAgIGRpc3QgPSA1MDAsIGRpc3RfdW5pdD0ibSIsIAogICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9MC4xOSwKICAgICAgICAgICAgICAgICAgICAgc3QuYm90dG9tPVRSVUUsIAogICAgICAgICAgICAgICAgICAgICBzdC5kaXN0PTAuMywKICAgICAgICAgICAgICAgICAgICAgc3Quc2l6ZT0zLjUsCiAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybSA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICBtb2RlbCA9ICdXR1M4NCcpIAojIFNDX3N0YW1lbl9tYXAKU0Nfc3RhbWVuX21hcCtub3J0aDIoU0Nfc3RhbWVuX21hcCwgeCA9IDAuODksIHkgPSAwLjg1LCBzY2FsZSA9IDAuMSwgc3ltYm9sID0gMTYpCmBgYAoKCgoKSW50ZXJhY3RpdmUgbWFwIG9mIEtERXMgYXQgU3RvbmUgQ2FueW9uCmBgYHtyfQpNNjdfS0RFPC1rZGVfYW5hbHlzaXMuaHJlZi5wb2x5Z29uKCcuL002Ny9NNjcgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQpNNjlfS0RFPC1rZGVfYW5hbHlzaXMuaHJlZi5wb2x5Z29uKCcuL002OS9NNjkgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQpNMjU1X0tERTwta2RlX2FuYWx5c2lzLmhyZWYucG9seWdvbignLi9NMjU1L00yNTUgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQpNMjE1X0tERTwta2RlX2FuYWx5c2lzLmhyZWYucG9seWdvbignLi9NMjE1L00yMTUgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQpNMTRfS0RFPC1rZGVfYW5hbHlzaXMuaHJlZi5wb2x5Z29uKCcuL00xNC9NMTQgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQpNMTE5X0tERTwta2RlX2FuYWx5c2lzLmhyZWYucG9seWdvbignLi9NMTE5L00xMTkgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQpNMTEyX0tERTwta2RlX2FuYWx5c2lzLmhyZWYucG9seWdvbignLi9NMTEyL00xMTIgLmNzdicsIHBlcmNlbnRhZ2U9IDk1KQoKRjY2X0tERTwta2RlX2FuYWx5c2lzLmhyZWYucG9seWdvbignLi9GNjYvRjY2IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjM2X0tERTwta2RlX2FuYWx5c2lzLmhyZWYucG9seWdvbignLi9GMzYvRjM2IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjI1Ml9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjI1Mi9GMjUyIC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjIxNF9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjIxNC9GMjE0IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjIwMF9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjIwMC9GMjAwIC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjE0N19LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjE0Ny9GMTQ3IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjE0Nl9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjE0Ni9GMTQ2IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjEzN19LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjEzNy9GMTM3IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjEzNV9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjEzNS9GMTM1IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjExNF9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjExNC9GMTE0IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKRjEwNF9LREU8LWtkZV9hbmFseXNpcy5ocmVmLnBvbHlnb24oJy4vRjEwNC9GMTA0IC5jc3YnLCBwZXJjZW50YWdlPSA5NSkKCk1hbGUuS0RFIDwtIHJiaW5kKE02N19LREUsTTY5X0tERSxNMjU1X0tERSxNMjE1X0tERSxNMTRfS0RFLE0xMTlfS0RFLE0xMTJfS0RFKQpGZW1hbGUuS0RFIDwtIHJiaW5kKEY2Nl9LREUsRjM2X0tERSxGMjUyX0tERSxGMjE0X0tERSxGMjAwX0tERSxGMTQ3X0tERSxGMTQ2X0tERSxGMTM3X0tERSwKICAgICAgICAgICAgICAgICAgICBGMTM1X0tERSxGMTE0X0tERSxGMTA0X0tERSkKCm1hcHZpZXdPcHRpb25zKGJhc2VtYXBzID0gYygiT3BlblN0cmVldE1hcCIsIkVzcmkuV29ybGRJbWFnZXJ5IiwiT3BlblRvcG9NYXAiKSwKICAgICAgICAgICAgICAgbmEuY29sb3IgPSAibWFnZW50YSIsCiAgICAgICAgICAgICAgIGxheWVycy5jb250cm9sLnBvcyA9ICJ0b3BsZWZ0IikKCm1hcHZpZXcoTWFsZS5LREUsIGxlZ2VuZD1GLCB6Y29sPSJpZCIsIGNvbC5yZWdpb25zID0gYygiYmx1ZSIpLCBhbHBoYS5yZWdpb25zPTAuMykgKyAKICBtYXB2aWV3KEZlbWFsZS5LREUsIGxlZ2VuZD1GLCB6Y29sID0gImlkIiwgY29sLnJlZ2lvbnMgPSBjKCJyZWQiKSwgYWxwaGEucmVnaW9ucz0wLjMpCmBgYAoKCgoKVEFCTEUgCmBgYHtyfQprYWJsZShyZWZfZGZSTV9rZGUsIGZvcm1hdCA9ICJwYW5kb2MiLCBjYXB0aW9uID0gJ1RhYmxlICB8IFN1YnNpZGl6ZWQgYW5kIG5vbi1zdWJzaWRpemVkIGRpcmVjdGlvbmFsIG1lYW5zIG9mIEtERSBob21lIHJhbmdlcyBhZnRlciBiZWluZyBhZGp1c3RlZCBmb3IgeWVhciwgc2V4IGFuZCBzYW1wbGUgc2l6ZS4nKQpgYGAKCgoKCiMjIyMjIyMjIyMjIyMjIyBTRUFTT05BTCBBTkFMWVNFUyAjIyMjIyMjIyMjIyMjIyMjIyMKCgpNYXAgb2Ygc2Vhc29uYWwgZmx1Y3Rpb25zIG9mIGhvbWUgcmFuZ2VzCmBgYHtyfQojIyBDcmVhdGUgTUNQIHBvbHlnb25zIGJ5IFNFQVNPTjoKTTIxNV9tY3AuRU08LW1jcF9hbmFseXNpcy5QT0xZKCIuL00yMTUvRW1lcmdlbmNlIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCk0yMTVfbWNwLkRSWTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vTTIxNS9EcnkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKTTIxNV9tY3AuTU9OPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NMjE1L01vbnNvb24gLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKCk0xMTJfbWNwLkRSWTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vTTExMi9EcnkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKTTExMl9tY3AuTU9OPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NMTEyL01vbnNvb24gLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKTTExMl9tY3AuUE08LW1jcF9hbmFseXNpcy5QT0xZKCIuL00xMTIvUG9zdF9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCgpNMTE5X21jcC5EUlk8LW1jcF9hbmFseXNpcy5QT0xZKCIuL00xMTkvRHJ5IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCk0xMTlfbWNwLk1PTjwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vTTExOS9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCk0xMTlfbWNwLlBNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9NMTE5L1Bvc3RfTW9uc29vbiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQoKRjExNF9tY3AuRU08LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxMTQvRW1lcmdlbmNlIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxMTRfbWNwLkRSWTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjExNC9EcnkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjExNF9tY3AuTU9OPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTE0L01vbnNvb24gLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjExNF9tY3AuUE08LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxMTQvUG9zdF9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCgpGMTM3X21jcC5FTTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjEzNy9FbWVyZ2VuY2UgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjEzN19tY3AuRFJZPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTM3L0RyeSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTM3X21jcC5NT048LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxMzcvTW9uc29vbiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTM3X21jcC5QTTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjEzNy9Qb3N0X01vbnNvb24gLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKCkYxNDdfbWNwLkVNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTQ3L0VtZXJnZW5jZSAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMTQ3X21jcC5EUlk8LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YxNDcvRHJ5IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxNDdfbWNwLk1PTjwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjE0Ny9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYxNDdfbWNwLlBNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMTQ3L1Bvc3RfTW9uc29vbiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQoKRjI1Ml9tY3AuRU08LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YyNTIvRW1lcmdlbmNlIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYyNTJfbWNwLkRSWTwtbWNwX2FuYWx5c2lzLlBPTFkoIi4vRjI1Mi9EcnkgLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjI1Ml9tY3AuTU9OPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMjUyL01vbnNvb24gLmNzdiIsIHBlcmNlbnRhZ2U9IDEwMCkKRjI1Ml9tY3AuUE08LW1jcF9hbmFseXNpcy5QT0xZKCIuL0YyNTIvUG9zdF9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCgpGMzZfbWNwLkVNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvRW1lcmdlbmNlIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYzNl9tY3AuRFJZPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvRHJ5IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkYzNl9tY3AuTU9OPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvTW9uc29vbiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGMzZfbWNwLlBNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GMzYvUG9zdF9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCgpGNjZfbWNwLkVNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvRW1lcmdlbmNlIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkY2Nl9tY3AuRFJZPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvRHJ5IC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCkY2Nl9tY3AuTU9OPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvTW9uc29vbiAuY3N2IiwgcGVyY2VudGFnZT0gMTAwKQpGNjZfbWNwLlBNPC1tY3BfYW5hbHlzaXMuUE9MWSgiLi9GNjYvUG9zdF9Nb25zb29uIC5jc3YiLCBwZXJjZW50YWdlPSAxMDApCgojIyBGb3J0aWZ5IG1jcCBwb2x5Z29ucyBmb3IgZ2dwbG90MiAqU0VBU09OKjoKTTIxNV9tY3AuRU1UIDwtIGZvcnRpZnkoTTIxNV9tY3AuRU0sIHJlZ2lvbiA9ICJpZCIpCk0yMTVfbWNwLkRSWVQgPC0gZm9ydGlmeShNMjE1X21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCk0yMTVfbWNwLk1PTlQgPC0gZm9ydGlmeShNMjE1X21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCgpNMTEyX21jcC5EUllUIDwtIGZvcnRpZnkoTTExMl9tY3AuRFJZLCByZWdpb24gPSAiaWQiKQpNMTEyX21jcC5NT05UIDwtIGZvcnRpZnkoTTExMl9tY3AuTU9OLCByZWdpb24gPSAiaWQiKQpNMTEyX21jcC5QTVQgPC0gZm9ydGlmeShNMTEyX21jcC5QTSwgcmVnaW9uID0gImlkIikKCk0xMTlfbWNwLkRSWVQgPC0gZm9ydGlmeShNMTE5X21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCk0xMTlfbWNwLk1PTlQgPC0gZm9ydGlmeShNMTE5X21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCk0xMTlfbWNwLlBNVCA8LSBmb3J0aWZ5KE0xMTlfbWNwLlBNLCByZWdpb24gPSAiaWQiKQoKRjExNF9tY3AuRU1UIDwtIGZvcnRpZnkoRjExNF9tY3AuRU0sIHJlZ2lvbiA9ICJpZCIpCkYxMTRfbWNwLkRSWVQgPC0gZm9ydGlmeShGMTE0X21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCkYxMTRfbWNwLk1PTlQgPC0gZm9ydGlmeShGMTE0X21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCkYxMTRfbWNwLlBNVCA8LSBmb3J0aWZ5KEYxMTRfbWNwLlBNLCByZWdpb24gPSAiaWQiKQoKRjEzN19tY3AuRU1UIDwtIGZvcnRpZnkoRjEzN19tY3AuRU0sIHJlZ2lvbiA9ICJpZCIpCkYxMzdfbWNwLkRSWVQgPC0gZm9ydGlmeShGMTM3X21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCkYxMzdfbWNwLk1PTlQgPC0gZm9ydGlmeShGMTM3X21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCkYxMzdfbWNwLlBNVCA8LSBmb3J0aWZ5KEYxMzdfbWNwLlBNLCByZWdpb24gPSAiaWQiKQoKRjE0N19tY3AuRU1UIDwtIGZvcnRpZnkoRjE0N19tY3AuRU0sIHJlZ2lvbiA9ICJpZCIpCkYxNDdfbWNwLkRSWVQgPC0gZm9ydGlmeShGMTQ3X21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCkYxNDdfbWNwLk1PTlQgPC0gZm9ydGlmeShGMTQ3X21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCkYxNDdfbWNwLlBNVCA8LSBmb3J0aWZ5KEYxNDdfbWNwLlBNLCByZWdpb24gPSAiaWQiKQoKRjI1Ml9tY3AuRU1UIDwtIGZvcnRpZnkoRjI1Ml9tY3AuRU0sIHJlZ2lvbiA9ICJpZCIpCkYyNTJfbWNwLkRSWVQgPC0gZm9ydGlmeShGMjUyX21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCkYyNTJfbWNwLk1PTlQgPC0gZm9ydGlmeShGMjUyX21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCkYyNTJfbWNwLlBNVCA8LSBmb3J0aWZ5KEYyNTJfbWNwLlBNLCByZWdpb24gPSAiaWQiKQoKRjM2X21jcC5FTVQgPC0gZm9ydGlmeShGMzZfbWNwLkVNLCByZWdpb24gPSAiaWQiKQpGMzZfbWNwLkRSWVQgPC0gZm9ydGlmeShGMzZfbWNwLkRSWSwgcmVnaW9uID0gImlkIikKRjM2X21jcC5NT05UIDwtIGZvcnRpZnkoRjM2X21jcC5NT04sIHJlZ2lvbiA9ICJpZCIpCkYzNl9tY3AuUE1UIDwtIGZvcnRpZnkoRjM2X21jcC5QTSwgcmVnaW9uID0gImlkIikKCkY2Nl9tY3AuRU1UIDwtIGZvcnRpZnkoRjY2X21jcC5FTSwgcmVnaW9uID0gImlkIikKRjY2X21jcC5EUllUIDwtIGZvcnRpZnkoRjY2X21jcC5EUlksIHJlZ2lvbiA9ICJpZCIpCkY2Nl9tY3AuTU9OVCA8LSBmb3J0aWZ5KEY2Nl9tY3AuTU9OLCByZWdpb24gPSAiaWQiKQpGNjZfbWNwLlBNVCA8LSBmb3J0aWZ5KEY2Nl9tY3AuUE0sIHJlZ2lvbiA9ICJpZCIpCgptY3Auc2hpZnQuVEVTVDUgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMTRfbWNwLkVNVCwgYWVzKHg9RjExNF9tY3AuRU1UJGxvbmcsIHk9RjExNF9tY3AuRU1UJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsdWUiLGxpbmV0eXBlPTIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTE0X21jcC5EUllULCBhZXMoeD1GMTE0X21jcC5EUllUJGxvbmcsIHk9RjExNF9tY3AuRFJZVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJyZWQiLGxpbmV0eXBlPTMpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTE0X21jcC5NT05ULCBhZXMoeD1GMTE0X21jcC5NT05UJGxvbmcsIHk9RjExNF9tY3AuTU9OVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJncmVlbiIsbGluZXR5cGU9NCkgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMTRfbWNwLlBNVCwgYWVzKHg9RjExNF9tY3AuUE1UJGxvbmcsIHk9RjExNF9tY3AuUE1UJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsYWNrIixsaW5ldHlwZT01KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjEzN19tY3AuRU1ULCBhZXMoeD1GMTM3X21jcC5FTVQkbG9uZywgeT1GMTM3X21jcC5FTVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmx1ZSIsbGluZXR5cGU9MikgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMzdfbWNwLkRSWVQsIGFlcyh4PUYxMzdfbWNwLkRSWVQkbG9uZywgeT1GMTM3X21jcC5EUllUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9InJlZCIsbGluZXR5cGU9MykgKwogIGdlb21fcG9seWdvbihkYXRhPUYxMzdfbWNwLk1PTlQsIGFlcyh4PUYxMzdfbWNwLk1PTlQkbG9uZywgeT1GMTM3X21jcC5NT05UJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImdyZWVuIixsaW5ldHlwZT00KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjEzN19tY3AuUE1ULCBhZXMoeD1GMTM3X21jcC5QTVQkbG9uZywgeT1GMTM3X21jcC5QTVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTUpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTQ3X21jcC5FTVQsIGFlcyh4PUYxNDdfbWNwLkVNVCRsb25nLCB5PUYxNDdfbWNwLkVNVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibHVlIixsaW5ldHlwZT0yKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjE0N19tY3AuRFJZVCwgYWVzKHg9RjE0N19tY3AuRFJZVCRsb25nLCB5PUYxNDdfbWNwLkRSWVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0icmVkIixsaW5ldHlwZT0zKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjE0N19tY3AuTU9OVCwgYWVzKHg9RjE0N19tY3AuTU9OVCRsb25nLCB5PUYxNDdfbWNwLk1PTlQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iZ3JlZW4iLGxpbmV0eXBlPTQpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMTQ3X21jcC5QTVQsIGFlcyh4PUYxNDdfbWNwLlBNVCRsb25nLCB5PUYxNDdfbWNwLlBNVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9NSkgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9RjI1Ml9tY3AuRU1ULCBhZXMoeD1GMjUyX21jcC5FTVQkbG9uZywgeT1GMjUyX21jcC5FTVQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9MikgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9RjI1Ml9tY3AuRFJZVCwgYWVzKHg9RjI1Ml9tY3AuRFJZVCRsb25nLCB5PUYyNTJfbWNwLkRSWVQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9MykgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9RjI1Ml9tY3AuTU9OVCwgYWVzKHg9RjI1Ml9tY3AuTU9OVCRsb25nLCB5PUYyNTJfbWNwLk1PTlQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9NCkgKwogICMgZ2VvbV9wb2x5Z29uKGRhdGE9RjI1Ml9tY3AuUE1ULCBhZXMoeD1GMjUyX21jcC5QTVQkbG9uZywgeT1GMjUyX21jcC5QTVQkbGF0KSwKICAjICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJibGFjayIsbGluZXR5cGU9NSkgKwogIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuRU1ULCBhZXMoeD1GMzZfbWNwLkVNVCRsb25nLCB5PUYzNl9tY3AuRU1UJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsdWUiLGxpbmV0eXBlPTIpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMzZfbWNwLkRSWVQsIGFlcyh4PUYzNl9tY3AuRFJZVCRsb25nLCB5PUYzNl9tY3AuRFJZVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJyZWQiLGxpbmV0eXBlPTMpICsKICBnZW9tX3BvbHlnb24oZGF0YT1GMzZfbWNwLk1PTlQsIGFlcyh4PUYzNl9tY3AuTU9OVCRsb25nLCB5PUYzNl9tY3AuTU9OVCRsYXQpLAogICAgICAgICAgICAgICBhbHBoYT0wLjEsY29sb3VyPSJncmVlbiIsbGluZXR5cGU9NCkgKwogIGdlb21fcG9seWdvbihkYXRhPUYzNl9tY3AuUE1ULCBhZXMoeD1GMzZfbWNwLlBNVCRsb25nLCB5PUYzNl9tY3AuUE1UJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImJsYWNrIixsaW5ldHlwZT01KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjY2X21jcC5FTVQsIGFlcyh4PUY2Nl9tY3AuRU1UJGxvbmcsIHk9RjY2X21jcC5FTVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmx1ZSIsbGluZXR5cGU9MikgKwogIGdlb21fcG9seWdvbihkYXRhPUY2Nl9tY3AuRFJZVCwgYWVzKHg9RjY2X21jcC5EUllUJGxvbmcsIHk9RjY2X21jcC5EUllUJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9InJlZCIsbGluZXR5cGU9MykgKwogIGdlb21fcG9seWdvbihkYXRhPUY2Nl9tY3AuTU9OVCwgYWVzKHg9RjY2X21jcC5NT05UJGxvbmcsIHk9RjY2X21jcC5NT05UJGxhdCksCiAgICAgICAgICAgICAgIGFscGhhPTAuMSxjb2xvdXI9ImdyZWVuIixsaW5ldHlwZT00KSArCiAgZ2VvbV9wb2x5Z29uKGRhdGE9RjY2X21jcC5QTVQsIGFlcyh4PUY2Nl9tY3AuUE1UJGxvbmcsIHk9RjY2X21jcC5QTVQkbGF0KSwKICAgICAgICAgICAgICAgYWxwaGE9MC4xLGNvbG91cj0iYmxhY2siLGxpbmV0eXBlPTUpICsKICB0aGVtZV9idygpICsKICBsYWJzKHg9IkVhc3RpbmcgKG0pIiwgeT0iTm9ydGhpbmcgKG0pIikgKwogIGxhYnMoY2FwdGlvbiA9ICJGaWd1cmUgNiB8ICBTQyBzZWFzb25hbCBob21lIHJhbmdlIHNoaWZ0cyBvZiBmaXZlIGxpemFyZHMuIEFsbCBzZWFzb25hbCBwb2x5Z29ucyBzdGF5IHJlbGF0aXZlbHkgc3RhYmxlIHdpdGggXG4gY29uc2lkZXJhYmxlIG92ZXJsYXAgYW5kIHdpdGhvdXQgYW55IG1ham9yIHNoaWZ0cy4iKSsKICB0aGVtZShwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLGxpbmVoZWlnaHQgPSAwLjkpKSsKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gMC41KSkKCm1jcC5zaGlmdC5URVNUNQpgYGAKCgoKClRBQkxFIGdyb3VwIG1lYW5zICBvZiBzZWFzb25hbCBob21lIHJhbmdlcyBiZXR3ZWVuIHRoZSAgdHdvICBwb3B1bGF0aW9ucyBhdmVyYWdlZCBhY3Jvc3Mgc2V4CmBgYHtyfQpzZWFzb25hbDwtcmVhZC5jc3YoIlNDX1NlYXNvbmFsX0RhdGEuY3N2IikKCmxpYnJhcnkoUm1pc2MpCgpTRUFTX0dSUF9NZWFucyA8LSBzdW1tYXJ5U0Uoc2Vhc29uYWwsIG1lYXN1cmV2YXI9IkhvbWVfUmFuZ2VfMTAwbWNwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwdmFycz1jKCJFbnZpcm9ubWVudCIsIlNlYXNvbiIpLCBuYS5ybSA9IFRSVUUpCgojIFNFQVNfR1JQX01lYW5zCmthYmxlKFNFQVNfR1JQX01lYW5zLCBmb3JtYXQgPSAicGFuZG9jIiwgY2FwdGlvbiA9ICdUYWJsZSA2IHwgR3JvdXAgbWVhbnMgb2Ygc2Vhc29uYWwgaG9tZSByYW5nZXMgYmV0d2VlbiBTdG9uZSBDYW55b24gKHN1YnNpZGl6ZWQpIGFuZCBPd2wgSGVhZCBCdXR0ZXMgKG5vbi1zdWJzaWRpemVkKS4gVGhlc2UgbWVhbnMgYXJlIGF2ZXJhZ2VkIGFjcm9zcyBzZXguJykKYGBgCgoKCgpSTS1BTk9WQSBmb3Igc2Vhc29uYWwgaG9tZSByYW5nZXMgYmV0d2VlbiBlbnZpcm9ubWVudHMKYGBge3J9CmxpYnJhcnkobG1lNCkKbGlicmFyeShyZWFkcikKbGlicmFyeShsbWVyVGVzdCkKIyBzZWFzb25hbDwtcmVhZC5jc3YoIlNDX1NlYXNvbmFsX0RhdGEuY3N2IikKClJNLm1vZC5TZWFzb24gPC0gbG1lcihIb21lX1JhbmdlXzEwMG1jcH5FbnZpcm9ubWVudCtTZWFzb24rU2V4K04rRW52aXJvbm1lbnQqU2Vhc29uKygxfEdpbGEpLCAKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9c2Vhc29uYWwpCnN1bW1hcnkoUk0ubW9kLlNlYXNvbikKYGBgCgoKQU5PVkEgdGFibGUgb2Ygc2Vhc29uYWwgSFJzIGJldHdlZW4gZW52cy4KYGBge3J9CmFub3ZhKFJNLm1vZC5TZWFzb24pCmBgYAoKCgoKVEFCTEUgb2Ygc2Vhc29uYWwgaG9tZSByYW5nZXMgYnkgc2V4IGJldHdlZW4gdGhlIHR3byBwb3B1bGF0aW9ucwpgYGB7cn0KU0VBU19HUlBfVEVTVCA8LSBzdW1tYXJ5U0Uoc2Vhc29uYWwsIG1lYXN1cmV2YXI9IkhvbWVfUmFuZ2VfMTAwbWNwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXB2YXJzPWMoIkVudmlyb25tZW50IiwiU2Vhc29uIiwiU2V4IiksIG5hLnJtID0gVFJVRSkKCiMgU0VBU19HUlBfTWVhbnMKa2FibGUoU0VBU19HUlBfVEVTVCwgZm9ybWF0ID0gInBhbmRvYyIsIGNhcHRpb24gPSAnVGFibGUgNyB8IFNlYXNvbmFsIGhvbWUgcmFuZ2UgbWVhbnMgYmV0d2VlbiBTdG9uZSBDYW55b24gKHN1YnNpZGl6ZWQpIGFuZCBPd2wgSGVhZCBCdXR0ZXMgKG5vbi1zdWJzaWRpemVkKSBwb3B1YXRpb25zIGZvciBtYWxlcyBhbmQgZmVtYWxlcy4gVGhlc2UgYXJlIHJhdyBtZWFucyBiZWZvcmUgYmVpbmcgYWRqdXN0ZWQgZm9yIGVudmlyb25tZW50LCBzZWFzb24sIHNleCwgYW5kIHNhbXBsZSBzaXplLicpCmBgYAoKCgoKZmlndXJlcyBmb3IgcmF3IHNlYXNvbmFsIGhvbWUgcmFuZ2VzIGJldHdlZW4gdGhlIHR3byBwb3B1bGF0aW9ucwpgYGB7cn0KcGQgPC0gcG9zaXRpb25fZG9kZ2UoMC4zKSAjIG1vdmUgdGhlbSAuMDUgdG8gdGhlIGxlZnQgYW5kIHJpZ2h0ICgnZG9kZ2VzJykKCiMgcmVsZXZlbCBmYWN0b3Igc2Vhc29uOgpTRUFTX0dSUF9URVNUJFNlYXNvbjwtcmVsZXZlbChTRUFTX0dSUF9URVNUJFNlYXNvbiwiRW1lcmdlbmNlIikKCiMgTmV3IGZhY2V0IGxhYmVsIG5hbWVzIGZvciBzZWFzb25zCiMgc2Vhc29uLmxhYnMgPC0gYygiRHJ5IiwgIkVtZXJnZW5jZSIsICJNb25zb29uIiwgIlBvc3QgTW9uc29vbiIpCiMgbmFtZXMoc2Vhc29uLmxhYnMpIDwtIGMoIkRyeSIsICJFbWVyZ2VuY2UiLCAiTW9uc29vbiIsICJQb3N0X01vbnNvb24iKQoKc2Vhc29uLmxhYnMgPC0gYygiRW1lcmdlbmNlIiwgIkRyeSIsICJNb25zb29uIiwgIlBvc3QgTW9uc29vbiIpCm5hbWVzKHNlYXNvbi5sYWJzKSA8LSBjKCJFbWVyZ2VuY2UiLCAiRHJ5IiwgIk1vbnNvb24iLCAiUG9zdF9Nb25zb29uIikKCiMjIFRFU1QgMwpyYXcuc2Vhc29uYWw8LWdncGxvdChTRUFTX0dSUF9URVNULGFlcyh4PUVudmlyb25tZW50LCB5PUhvbWVfUmFuZ2VfMTAwbWNwLCBzaGFwZT1TZXgpKSArIAogIGdlb21fcG9pbnQoYWVzKHNoYXBlPVNleCksIHNpemUgPSA0LCBwb3NpdGlvbj1wZCkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49SG9tZV9SYW5nZV8xMDBtY3Atc2UsIHltYXg9SG9tZV9SYW5nZV8xMDBtY3Arc2UpLCBwb3NpdGlvbiA9IHBkLAogICAgICAgICAgICAgICAgd2lkdGg9MC4zLCBzaXplPTAuNSwgbHR5PTEpICsKICBmYWNldF9ncmlkKH5TZWFzb24sIGxhYmVsbGVyPWxhYmVsbGVyKFNlYXNvbj1zZWFzb24ubGFicykpICsKICAgdGhlbWVfYncoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYyguODcsLjg1KSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChsaW5laGVpZ2h0PTEuNSwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEuNSksIGhqdXN0ID0gMC41KSwKICAgICAgICAjIGF4aXMudGV4dC54ICA9IGVsZW1lbnRfdGV4dCh2anVzdD0wLjUsIHNpemU9OCksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55ICA9IGVsZW1lbnRfdGV4dCh2anVzdD0wLjUsIHNpemU9OCksCiAgICAgICAgYXhpcy50aXRsZS55ICA9IGVsZW1lbnRfdGV4dChzaXplPTE2KSwKICAgICAgICBheGlzLnRpdGxlLnggID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIGF4aXMudGlja3MueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkgKwogIHhsYWIoIiIpICsgeWxhYigiMTAwJSBNQ1AgQXJlYSAoaGEpIikgCgpyYXcuc2Vhc29uYWwKYGBgCgoKCgpGaWd1cmVzIEFkanVzdGVkIEVNTXMgb2Ygc2Vhc29uYWwgaG9tZSByYW5nZSBiZXR3ZWVuIHRoZSB0d28gcG9wdWxhdGlvbnMKYGBge3J9ClJNLm1vZC5TZWFzb24gPC0gbG1lcihIb21lX1JhbmdlXzEwMG1jcH5FbnZpcm9ubWVudCtTZWFzb24rU2V4K04rRW52aXJvbm1lbnQqU2Vhc29uKygxfEdpbGEpLCBkYXRhPXNlYXNvbmFsKQoKIyBSTS5tYXJnaW5hbCA8LSBsc21lYW5zKFJNLm1vZC5TZWFzb24sIAojICAgICAgICAgICAgICAgICAgICAgfiBFbnZpcm9ubWVudCkKIyBSTS5tYXJnaW5hbAoKIyMgQ0FUQUdPUklaRSBMU00gR1JBUEggQlkgU0VYIEJFVFdFRU4gRU5WSVJPTk1FTlQ6CnJlZlJNX3NlYXNvbiA8LSBsc21lYW5zKFJNLm1vZC5TZWFzb24sIHNwZWNzID0gYygiRW52aXJvbm1lbnQiLCJTZWFzb24iLCJTZXgiKSkKCiMgcmVmUk1fc2V4CnJlZl9kZlJNX3NlYXNvbiA8LSBhcy5kYXRhLmZyYW1lKHN1bW1hcnkocmVmUk1fc2Vhc29uKSkKcGRfUk0gPC0gcG9zaXRpb25fZG9kZ2UoMC4yKQoKIyByZWxldmVsIGZhY3RvciBzZWFzb24gZm9yIGdyYXBoaW5nIHB1cnBvc2VzOgpyZWZfZGZSTV9zZWFzb24kU2Vhc29uPC1yZWxldmVsKHJlZl9kZlJNX3NlYXNvbiRTZWFzb24sIkVtZXJnZW5jZSIpCgojIE5ldyBmYWNldCBsYWJlbCBuYW1lcyBmb3Igc2Vhc29ucwojIHNlYXNvbi5sYWJzIDwtIGMoIkRyeSIsICJFbWVyZ2VuY2UiLCAiTW9uc29vbiIsICJQb3N0IE1vbnNvb24iKQojIG5hbWVzKHNlYXNvbi5sYWJzKSA8LSBjKCJEcnkiLCAiRW1lcmdlbmNlIiwgIk1vbnNvb24iLCAiUG9zdF9Nb25zb29uIikKCiMgc2Vhc29uLmxhYnMgPC0gYygiRW1lcmdlbmNlIiwgIkRyeSIsICJNb25zb29uIiwgIlBvc3QgTW9uc29vbiIpCiMgbmFtZXMoc2Vhc29uLmxhYnMpIDwtIGMoIkVtZXJnZW5jZSIsICJEcnkiLCAiTW9uc29vbiIsICJQb3N0X01vbnNvb24iKQoKYWRqLnNlYXNvbmFsPC1nZ3Bsb3QocmVmX2RmUk1fc2Vhc29uLGFlcyh4PUVudmlyb25tZW50LCB5PWxzbWVhbiwgc2hhcGU9U2V4KSkgKyAKICBnZW9tX3BvaW50KGFlcyhzaGFwZT1TZXgpLCBzaXplID0gNCwgcG9zaXRpb249cGQsIHNob3cubGVnZW5kPUZBTFNFKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDEsIDIpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1sc21lYW4tU0UsIHltYXg9bHNtZWFuK1NFKSwgcG9zaXRpb24gPSBwZCwKICAgICAgICAgICAgICAgIHdpZHRoPTAuMywgc2l6ZT0wLjUsIGx0eT0xKSArIAogIGZhY2V0X2dyaWQoflNlYXNvbiwgbGFiZWxsZXI9bGFiZWxsZXIoU2Vhc29uPXNlYXNvbi5sYWJzKSkgKwogIHRoZW1lX2J3KCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYyguODcsLjg1KSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggID0gZWxlbWVudF90ZXh0KHZqdXN0PTAuNSwgc2l6ZT0xNiksCiAgICAgICAgYXhpcy50ZXh0LnkgID0gZWxlbWVudF90ZXh0KHZqdXN0PTAuNSwgc2l6ZT04KSwKICAgICAgICBheGlzLnRpdGxlLnkgID0gZWxlbWVudF90ZXh0KHNpemU9MTYpLAogICAgICAgIGF4aXMudGl0bGUueCAgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksCiAgICAgICAgIyBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCJOb24iLCAiU3ViIikpICsKICB4bGFiKCIiKSArIHlsYWIoIjEwMCUgTUNQIEFyZWEgKGhhKSIpCgphZGouc2Vhc29uYWwKYGBgCgoKQ29sbGVjdGl2ZSBncmlkIG9mIHJhdyBhbmQgYWRqdXN0ZWQgc2Vhc29uYWwgaG9tZSByYW5nZXMKYGBge3J9CmdnYXJyYW5nZShyYXcuc2Vhc29uYWwsIGFkai5zZWFzb25hbCwgbGFiZWxzID0gYygiQSIsICJCIiksCiAgICAgICAgICBucm93ID0gMikKYGBgCgoKCgpQb3N0IGhvYyBhbmFseXNlcyBvZiBzZWFzb25hbCBob21lIHJhbmdlcwoKUGFpcndpc2Ugb2YgZWFjaCBzZWFzb24gYmV0d2VlbiBwb3B1bGF0aW9ucywgb3ZlcmFnZWQgb3ZlciBsZXZlbHMgb2Ygc2V4CmBgYHtyfQplbW1fcy50IDwtIGVtbWVhbnMoUk0ubW9kLlNlYXNvbiwgcGFpcndpc2UgfiBFbnZpcm9ubWVudCB8IFNlYXNvbikKZW1tX3MudApgYGAKCkdyYXBoaWNhbCBjb21wYXJpc29ucwpgYGB7cn0KcGxvdChlbW1fcy50LCBjb21wYXJpc29ucyA9IFRSVUUpCmBgYAoKCgoKUGFpcndpc2UgYmV0d2VlbiBzZWFzb25zIHdpdGhpbiBlYWNoIHBvcHVsdGlvbiAKYGBge3J9CmVtbV9zLnQ0IDwtIGVtbWVhbnMoUk0ubW9kLlNlYXNvbiwgcGFpcndpc2UgfiBTZWFzb24gfCBFbnZpcm9ubWVudCkKZW1tX3MudDQKYGBgCgpHcmFwaGljYWwgQ29tcHMKYGBge3J9CnBsb3QoZW1tX3MudDQsIGNvbXBhcmlzb25zID0gVFJVRSkKYGBgCgoKClBhaXJ3aXNlIGJldHdlZW4gc2V4ZXMgb2YgZWFjaCBzZWFzb24gb2YgdGhlICBzdWJzaWRpemVkIHBvcHVsYXRpb24KYGBge3J9CnN1YiA8LSBzdWJzZXQoc2Vhc29uYWwsIEVudmlyb25tZW50ID09ICJzdWJzaWRpemVkIikKClJNLm1vZC5TdWIgPC0gbG1lcihIb21lX1JhbmdlXzEwMG1jcH5TZWFzb24rU2V4K04rU2Vhc29uKlNleCsoMXxHaWxhKSwgZGF0YT1zdWIpCgplbW1fcy50NSA8LSBlbW1lYW5zKFJNLm1vZC5TdWIsIHBhaXJ3aXNlIH4gU2V4IHwgU2Vhc29uKQplbW1fcy50NSAKYGBgCgpHcmFwaGljYWwgQ29tcHMKYGBge3J9CnBsb3QoZW1tX3MudDUsIGNvbXBhcmlzb25zID0gVFJVRSkKYGBgCgoKClBhaXJ3aXNlIGJldHdlZW4gc2V4ZXMgb2YgZWFjaCBzZWFzb24gb2YgdGhlICBub24tc3Vic2lkaXplZCBwb3B1bGF0aW9uCmBgYHtyfQpub25zdWIgPC0gc3Vic2V0KHNlYXNvbmFsLCBFbnZpcm9ubWVudCA9PSAibm9uc3Vic2lkaXplZCIpClZpZXcobm9uc3ViKQpSTS5tb2QuTlN1YiA8LSBsbWVyKEhvbWVfUmFuZ2VfMTAwbWNwflNlYXNvbitTZXgrTitTZWFzb24qU2V4KygxfEdpbGEpLCBkYXRhPW5vbnN1YikKCmVtbV9zLnQ2IDwtIGVtbWVhbnMoUk0ubW9kLk5TdWIsIHBhaXJ3aXNlIH4gU2V4IHwgU2Vhc29uKQplbW1fcy50NiAKYGBgCgpHcmFwaGljYWwgQ29tcHMKYGBge3J9CnBsb3QoZW1tX3MudDYsIGNvbXBhcmlzb25zID0gVFJVRSkKYGBgCgoKCgo=